C++11多线程

参考:

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

http://blog.jobbole.com/44409/

线程

类std::thread代表一个可执行线程,使用时必须包含头文件<thread>。std::thread可以和普通函数,匿名函数和仿函数(一个实现了operator()函数的类)一同使用。另外,它允许向线程函数传递任意数量的参数。

#include <thread>

void func()
{
   // do some work
}

int main()
{
   std::thread t(func);
   t.join();

   return 0;
}

上例中,t 是一个线程对象,函数func()运行于该线程中。对join()函数的调用将使调用线程(本例是指主线程)一直处于阻塞状态,直到正在执行的线程t执行结束。如果线程函数返回某个值,该值也将被忽略。不过,该函数可以接收任意数量的参数。

 1 void func(int i, double d, const std::string& s)
 2 {
 3     std::cout << i << ", " << d << ", " << s << std::endl;
 4 }
 5  
 6 int main()
 7 {
 8    std::thread t(func, 1, 12.50, "sample");
 9    t.join();
10  
11    return 0;
12 }

尽管可以向线程函数传递任意数量的参数,但是所有的参数应当按值传递。如果需要将参数按引用传递,那要向下例所示那样,必须将参数用std::ref 或者std::cref进行封装。

void func(int& a)
{
   a++;
}
 
int main()
{
   int a = 42;
   std::thread t(func, std::ref(a));
   t.join();
 
   std::cout << a << std::endl;
 
   return 0;
}

该程序打印结果为43,但是如果不用std::ref把参数a进行封装的话,输出结果将为42

Detach: 允许执行该方法的线程脱离其线程对象而继续独立执行。脱离后的线程不再是可结合线程(你不能等待它们执行结束)。

int main()
{
    std::thread t(funct);
    t.detach();
 
    return 0;
}

互斥Mutex

C++ 11的<mutex>头文件里包含了四种不同的互斥量:

  • Mutex: 提供了核心函数 lock() 和 unlock(),以及非阻塞方法的try_lock()方法,一旦互斥量不可用,该方法会立即返回。
  • Recursive_mutex:允许在同一个线程中对一个互斥量的多次请求。
  • Timed_mutex:同上面的mutex类似,但它还有另外两个方法 try_lock_for() 和 try_lock_until(),分别用于在某个时间段里或者某个时刻到达之间获取该互斥量。
  • Recursive_timed_mutex: 结合了timed_mutex 和recuseive_mutex的使用。

std::mutex与win32的临界区(cirtical section)很类似。lock()如同EnterCriticalSection,unlock如同LeaveCriticalSection,try_lock则像TryEnterCriticalSection。

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。

std::recursive_mutex m;
void foo()
{
    m.lock();
    m.lock(); // now valid
    j++;
    m.unlock();
    m.unlock(); // don't forget!
}

 

posted on 2016-07-24 18:47  已停更  阅读(3611)  评论(2编辑  收藏  举报