zoukankan      html  css  js  c++  java
  • c++11 线程:让你的多线程任务更轻松

    英文原文:C++ 11 Threading: Make your (multitasking) life easier

    转载:http://www.oschina.net/translate/cplusplus-11-threading-make-your-multitasking-life

    介绍


    本文旨在帮助有经验的Win32程序员来了解c++ 11线程库及同步对象 和 Win32线程及同步对象之间的区别和相似之处。

    在Win32中,所有的同步对象句柄(HANDLE)是全局句柄.它们可以被共享,甚至可以在进程间复制。在C++11中,所有的同步对象都是栈(stack)对象,这意味着它们必须是可“分离(detached)”的(如果支持“分离”的话)以便能够被栈框架(stack frame)所析构。如果大量对象应该分离而你没有,那么它们便会无法实现自己的行动,而毁掉你的原本计划。(译者注:在pthread中,线程有joinable和unjoinable之分,具有joinable的线程在线程结束时,不会清空该线程所占用的栈空间,通常的做法是在pthrea_create创建线程后,再调用pthread_join(有点waitforsingleobject的意思)才会清空,而unjoinable的属性的线程在线程结束时,就会自动清空所占用空间)

    所有的c++11同步对象都有一个native_handle()成员,它返回具体实现句柄(在win32,它就是一个handle)


    背景知识

    我也是c++11线程的新手。你需要自己去了解win32同步相关知识。这里可能不是合适的同步技术的教程,而是一个C++11机制的快速引导,以便对你所指定的计划有所帮助。


    简单成就完美


    一个简单例子:启动一个线程,然后等它结束:

     
    1
    2
    3
    4
    5
    6
    7
    8
    void foo()
      {
      }
    void func()
      {
      std::thread t(foo); // Starts. Equal to CreateThread.
      t.join();  // Equal to WaitForSingleObject to the thread handle.
      }

    与win32线程不同,你可以在这里传递参数:

     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void foo(int x,int y)
      {
      // x = 4, y = 5.
      }
    void func()
      {
      std::thread t(foo,4,5); // Acceptable.
      t.join(); 
      }

    这样,通过传递‘this’指针给std::thread让成员函数成为一个线程,变成了一件很简单的事情.如果std::thread得以析构,而你没有调用join(),它将会异常终止。脱离c++封装运行线程:

    2
    3
    4
    5
    6
    7
    8
    9
    void foo()
      {
      }
    void func()
      {
          std::thread t(foo);
          // 在这里已经调用了detach方法,c++对象从win32对象中脱离出来,如果此时还调用join方法,就会抛出std::system_error()
          t.detach();
      }

    除了join(),detach()方法,还有joinable(),get_id(),sleep_for(),sleep_until().它们都是自解释的,很好理解。


    使用互斥(Mutex)

    std::mutex与win32的临界区(cirtical section)很类似。lock()如同EnterCriticalSectionunlock如同LeaveCriticalSectiontry_lock则像TryEnterCriticalSection

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    std::mutex m;
    int j = 0;
    void foo()
      {
      m.lock();        // 进入临界区域
      j++;
      m.unlock();      // 离开
      }
    void func()
      {
      std::thread t1(foo);
      std::thread t2(foo);
      t1.join();
      t2.join();
     // j = 2;
    }
     
     
     
     

    如上,你在lock一个 std::mutex 对象之后必须解锁(unlock)。如果你已经对其加锁,你不能再次lock。这与win32 不同,如果你已经在临界区(critical section)里,再次 EnterCriticalSection不会失败,但是会增加一个计数。

    前面提到不能对std::mutex重复lock。这里有std::recursive_mutex(谁发明的这名字),它的行为则与临界区(critical section)相似,可以重复lock。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    std::recursive_mutex m;
    void foo()
      {
      m.lock();
      m.lock(); // now valid
      j++;
      m.unlock();
      m.unlock(); // don't forget!
      }

    此外,还有 std::timed_mutexstd::recursive_timed_mutex,他们提供 try_lock_for/ try_lock_until方法,允许你等待一个lock,直到超时,或者达到定义的时间。


  • 相关阅读:
    lncRNA表达定量方法评估
    比对软件之STAR的使用方法
    怎么检测自己fastq的Phred类型 | phred33 phred64
    质控工具之TrimGalore使用方法
    怎么从bam文件中提取出比对OR没比对上的paired reads | bamToFastq | STAR
    RepBaseRepeatMaskerEdition下载 | RepeatMasker
    Nr,GenBank, RefSeq, UniProt 数据库的异同
    质控工具之cutadapt的使用方法
    初步了解hg19注释文件的内容 | gtf
    单细胞数据高级分析之消除细胞周期因素 | Removal of cell cycle effect
  • 原文地址:https://www.cnblogs.com/lhuan/p/5745978.html
Copyright © 2011-2022 走看看