按理来说学习多线程编程应该从深入浅的来学,但是由于学习的内容实在是有一些偏差,所以最后还是决定从stl标准库开始,学习C++多线程编程。
一 std::thread函数浅析
相比pthread,C++11提供了一个调用非常简单的多线程库std::thread。std::thread的构造函数方便得出人意料,这得感谢std::bind这个神奇的函数。在std::thread的构造函数里,你可以直接传递一个函数和这个函数的参数列表给这个线程。你甚至可以传递一个类成员函数。如果你这么做了,参数列表的第二个参数(第一个参数是被传递的成员函数)会被作为该类成员函数所作用的实例。
1 2 3 4 5 6 7 8 9 10
| std::thread Annie(buy);
std::thread Bob(buy, book, food);
Consumer Clara; std::thread action(buy, Clara, phone);
|
1 2
| pthread_create(&thread, &attr, f, static_cast<void *>(&args));
|
简单的mutex互斥锁实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<iostream> #include<thread> #include<mutex> std::mutex mut; class A{ public: volatile int temp; A(){ temp=0; } void fun(int num){ int count=10; while(count>0){ mut.lock(); temp++; std::cout<<"thread_"<<num<<"...temp="<<temp<<std::endl; mut.unlock(); count--; } }
void thread_run(){ std::thread t1(&A::fun,this,1); std::thread t2(&A::fun,this,2); t1.join(); t2.join(); } };
int main(){ A a; a.thread_run(); }
|
二 volatile 关键词
在C++中使用volatile关键词可以防止编译器做出错误的优化。当一个线程对一个关键字进行多次读取时,编译器可能会把变量放入寄存器中,而不会每次都从内存中读取,这样如果变量在其他地方修改,会发生脏读取错误。
三 基于std::thread实现的生产者消费者模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <chrono> #include <condition_variable> #include <future> #include <mutex> #include <queue>
std::mutex mutex; std::condition_variable condvar;
std::queue<int> msgQueue;
void producer(int start, int end){ for (int x = start; x < end; x++) { std::this_thread::sleep_for(std::chrono::milliseconds(200)); { std::lock_guard<std::mutex> guard(mutex); msgQueue.push(x); } printf("Produce message %d\n", x); condvar.notify_all(); } }
void consumer(int demand){ while (true) { std::unique_lock<std::mutex> ulock(mutex); condvar.wait(ulock, []{ return msgQueue.size() > 0;}); printf("Consume message %d\n", msgQueue.front()); msgQueue.pop(); --demand; if (!demand) break; } }
int main(){ std::thread producer1(producer, 0, 10); std::thread producer2(producer, 10, 20); std::thread producer3(producer, 20, 30); std::thread consumer1(consumer, 20); std::thread consumer2(consumer, 10);
producer1.join(); producer2.join(); producer3.join(); consumer1.join(); consumer2.join(); }
|
本文仅简单介绍std::thread的基本操作,更加复杂的操作以及更多的功能将在日后进一步研读。