简介
thread
C++11 引入了 std::thread 库以实现多线程
成员函数
- thread(funcName) - 构造函数,实例化线程
- join() - 调用该函数会阻塞当前线程,及让主线程等待子线程。需要注意的是线程对象执行了join后joinable就为false了,所以只能调用join一次。
- thread::detach() - 将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放
- get_id(),获取线程ID,返回一个类型为std::thread::id的对象
- joinable(),检查线程是否可被join
- native_handle,该函数返回与std::thread具体实现相关的线程句柄
锁(mutex)
mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据。
但是使用mutex是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去
成员函数
- lock() - 调用线程将锁住该互斥量
- unlock() - 解锁,释放对互斥量的所有权
- try_lock() - 尝试锁住互斥量,如果互斥量被其他线程占有,则当前线程也不会被阻塞。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int cnt = 20; mutex m; void fun() { while (cnt > 0) { m.lock(); if (cnt > 0) { --cnt; cout << cnt << endl; } m.unlock(); } } int main() { thread th1(fun); thread th2(fun); th1.join(); th2.join(); return 0; }
|
线程死锁及解决
但对变量加锁需要考虑特殊情况,如下
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
| int cnt = 20; mutex m; void fun(int n) { try { while (cnt > 0) { m.lock(); if (n == 1) throw("error"); if (cnt > 0) { --cnt; cout << this_thread::get_id() << " " << cnt << endl; } m.unlock(); } } catch (const char* e) { cout << this_thread::get_id() << " " << e << endl; } } int main() { thread th1(fun, 1); thread th2(fun, 2); th1.join(); th2.join(); return 0; }
|
输出为
上面的情况,就是出现了死锁,解决方法如下
可以使用 guard_lock
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
| int cnt = 20; mutex m;
void fun(int n) { try { while (cnt > 0) { lock_guard<mutex> lockGuard(m); if (n == 1) throw("error"); if (cnt > 0) { --cnt; cout << this_thread::get_id() << " " << cnt << endl; } } } catch (const char* e) { cout << this_thread::get_id() << " " << e << endl; } } int main() { thread th1(fun, 1); thread th2(fun, 2); th1.join(); th2.join(); return 0; }
|
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 23628 error 3848 19 3848 18 3848 17 3848 16 3848 15 3848 14 3848 13 3848 12 3848 11 3848 10 3848 9 3848 8 3848 7 3848 6 3848 5 3848 4 3848 3 3848 2 3848 1 3848 0
|
更多锁
更多有关于线程中锁的内容可查看C++-线程中的锁