C++11多线程编程
2017-08-15 14:50
337 查看
1. 基本的多线程实现
上述代码实现基本的线程调度,在主线程中调用线程t1,并将t1移动到t2中,这是t1为空。且主函数字符串s是通过传地址的方式给线程t1。
2. 主线程与子线程同步问题
输出结果:
3. 利用unique_lock实现主从线程同步
lock_guard 加锁保护,可以防止上锁的线程崩溃,而不能及时释放锁。而unique_lock可以提供更多的弹性,可以指定代码同步。用lock/unlock可以灵活的控制加锁同步的范围,但会消耗更多的计算机资源。
4. 如何避免死锁
lock(m_mutex, m_mutex2)有效的避免了死锁的发生,即使t1线程中的调用log.share_print2函数优先对m_mutex2加锁,也是按照lock设定的顺序执行的。
5. 条件变量提高线程效率
运行结果:
引入c++条件变量,#include,来控制子线程等待时间,使用condition_variable::wait(),表示等待上一个线程完成。
如有问题,请指教,谢谢!
#include<iostream> #include<thread> #include<string> using namespace std; class Factor { public: void operator()(string &msg) { cout << "from t1:" << msg << endl; msg = "Read http://blog.csdn.net/hutianyou123"; } }; int main() { string s = "http://blog.csdn.net/hutianyou123"; cout << this_thread::get_id() << endl; std::thread t1((Factor()),move(s)); thread t2 = move(t1); cout << t2.get_id() << endl; t2.join(); //thread::hardware_concurrency(); system("pause"); return 0; }
上述代码实现基本的线程调度,在主线程中调用线程t1,并将t1移动到t2中,这是t1为空。且主函数字符串s是通过传地址的方式给线程t1。
2. 主线程与子线程同步问题
#include<iostream> #include<string> #include<thread> #include<mutex> #include<fstream> using namespace std; class Logfile { public: Logfile() { f.open("log.txt"); } void share_print(string msg, int id) { lock_guard<mutex>locker(m_mutex);//加同步锁 f << msg << ":" << id << endl; cout << msg << ":" << id << endl; } protected: private: mutex m_mutex; ofstream f; }; void function_1(Logfile &log) { for (int i = 0; i < 100; i++) log.share_print("From t1:", i); } int main() { Logfile log; thread t1(function_1,ref(log)); for (int i = 0; i >-100; i--) log.share_print("From main:", i); if(t1.joinable()) t1.join(); system("pause"); return 0; }
输出结果:
3. 利用unique_lock实现主从线程同步
#include<iostream> #include<string> #include<thread> #include<mutex> #include<fstream> #include<windows.h> using namespace std; class Logfile { once_flag m_flag; public: Logfile() { } void share_print(string msg, int id) { call_once(m_flag, [&]() {f.open(("log.txt")); }); unique_lock<mutex>locker(m_mutex,defer_lock);//加同步锁 locker.lock(); cout<< msg << ":" << id << endl; locker.unlock(); f << msg << ":" << id << endl; } private: mutex m_mutex; ofstream f; }; void function_1(Logfile &log) { for (int i = 0; i < 100; i++) log.share_print("From t1:", i); } int main() { Logfile log; thread t1(function_1, ref(log)); for (int i = 0; i > -100; i--) { log.share_print("From main:", i); } if (t1.joinable()) t1.join(); system("pause"); return 0; }
lock_guard 加锁保护,可以防止上锁的线程崩溃,而不能及时释放锁。而unique_lock可以提供更多的弹性,可以指定代码同步。用lock/unlock可以灵活的控制加锁同步的范围,但会消耗更多的计算机资源。
4. 如何避免死锁
#include<iostream> #include<string> #include<thread> #include<mutex> #include<fstream> #include<windows.h> using namespace std; class Logfile { public: Logfile() { f.open("log.txt"); } void share_print(string msg, int id) { lock(m_mutex, m_mutex2);//对mutex按照顺序加锁 lock_guard<mutex>locker(m_mutex,adopt_lock);//加同步锁 lock_guard<mutex>locker2(m_mutex2,adopt_lock);//加同步锁 cout<< msg << ":" << id << endl; } void share_print2(string msg, int id) { lock(m_mutex, m_mutex2); lock_guard<mutex>locker2(m_mutex2,adopt_lock);//加同步锁 lock_guard<mutex>locker(m_mutex,adopt_lock);//加同步锁 cout << msg << ":" << id << endl; } private: mutex m_mutex; mutex m_mutex2; ofstream f; }; void function_1(Logfile &log) { for (int i = 0; i < 100; i++) log.share_print("From t1:", i); } int main() { Logfile log; thread t1(function_1, ref(log)); for (int i = 0; i > -100; i--) { log.share_print2("From main:", i); } if (t1.joinable()) t1.join(); system("pause"); return 0; }
lock(m_mutex, m_mutex2)有效的避免了死锁的发生,即使t1线程中的调用log.share_print2函数优先对m_mutex2加锁,也是按照lock设定的顺序执行的。
5. 条件变量提高线程效率
#include<iostream> #include<deque> #include<string> #include<thread> #include<mutex> #include<fstream> #include<condition_variable> using namespace std; condition_variable cond; deque<int>q; mutex mu; void function_1() { int count = 10; while (count > 0) { unique_lock<mutex>locker(mu); q.push_front(count);//给队列加锁 locker.unlock(); cond.notify_one();//标注条件变量 this_thread::sleep_for(chrono::seconds(1));//休眠1秒钟 count--; } } void function_2() { int data = 0; while (data != 1) { unique_lock<mutex>locker(mu);//加锁 cond.wait(locker, []() {return !q.empty(); });//当队列为空,线程处于休眠状态 data = q.back();//从队列获取数据 q.pop_back(); locker.unlock(); cout << "to got a value from t1: " << data << endl; } } int main() { thread t1(function_1); thread t2(function_2); t1.detach();//无需等待t1线程运行结束 t2.join();//等待t2线程运行结束 system("pause"); return 0; }
运行结果:
引入c++条件变量,#include,来控制子线程等待时间,使用condition_variable::wait(),表示等待上一个线程完成。
如有问题,请指教,谢谢!
相关文章推荐
- c++11多线程编程(十):packaged_task<>介绍与实例
- C++11多线程编程
- c++11多线程编程(一):创建线程的三种方法
- c++11多线程编程(二):joining和detaching 线程
- c++11多线程编程(四):数据共享和竞争条件
- C++11 多线程编程
- c++11多线程编程(五):使用mutex修复竞争
- c++11多线程编程(八):std::future , std::promise和线程的返回值
- c++11多线程编程(三):仔细地将参数传递给线程
- C++11 多线程编程
- c++11多线程编程(七):条件变量说明
- c++11多线程编程(六):事件处理
- c++11多线程编程(九):std::async介绍与实例
- linux下的C语言开发(多线程编程)
- C++11的新特性简单汇总介绍 (二)
- C++11: 使用 lambda 创建模板类 的 对象
- functional助力C++11实现高度可重用接口-线程池例子
- Qt中的多线程编程
- C++11 —— 基于区间(range)的 for 循环
- Linux 多线程编程( POSIX )( 六 )----->共享内存区