多线程程序
竞态条件:多线程程序执行的结果是一致的,不会随着CPU对线程不同的调用顺序而产生不同的运行结果.

解决?:互斥锁 mutex

经典的卖票问题,三个线程卖100张票

代码1

#include #include #include #include int ticketCount = 100;std::mutex mtx;//互斥锁void sellTicket(int window) {while (ticketCount > 0) {mtx.lock();std::cout << "窗口" << window << "销售" << ticketCount << std::endl;ticketCount--;mtx.unlock();std::this_thread::sleep_for(std::chrono::milliseconds(50));}}//endint main() {std::list tlist;for (int i = 0; i < 3; i++) {tlist.push_back(std::thread(sellTicket,i));}for (std::thread & t : tlist) {t.join();}system("pause");return 0;}

上面代码的问题…

while (ticketCount > 0) {    mtx.lock();    std::cout << "窗口" << window << "销售" << ticketCount < 0)为true,线程A还没执行ticketCount--完成时,cpu交给了线程B线程B while (ticketCount > 0)也为true,进入 循环体内,造成了买0号票,改进如下

代码2

#include #include #include #include int ticketCount = 100;std::mutex mtx;//互斥锁void sellTicket(int window) {while (ticketCount > 0) {mtx.lock();                if(ticketCount >0){  std::cout << "窗口" << window << "销售" << ticketCount << std::endl;  ticketCount--;                }mtx.unlock();std::this_thread::sleep_for(std::chrono::milliseconds(50));}}//endint main() {std::list tlist;for (int i = 0; i < 3; i++) {tlist.push_back(std::thread(sellTicket,i));}for (std::thread & t : tlist) {t.join();}system("pause");return 0;}

代码2还有些问题!! 如下

mtx.lock();代码代码代码代码.....mtx.unlock();如果在代码lock()和unlock()之间 非常返回,导致mtx没有正常unlock(),那么出现死锁问题 =》智能指针  lock_gurad unique_lock

看lock_gurad

#include #include #include #include int ticketCount = 100;std::mutex mtx;//互斥锁void sellTicket(int window) {while (ticketCount > 0) {{std::lock_guard lock(mtx);std::cout << "窗口" << window << "销售" << ticketCount << std::endl;ticketCount--;std::this_thread::sleep_for(std::chrono::milliseconds(50));}}}//endint main() {std::list tlist;for (int i = 0; i < 3; i++) {tlist.push_back(std::thread(sellTicket,i));}for (std::thread & t : tlist) {t.join();}system("pause");return 0;}

上面的图片中我们知道lock_gurad 的拷贝构造函数被关闭了,所以当我们遇到函数调用需要拷贝构造lock_guard的时候,就有障碍了,这个时候可以用unique_lock

unique_lock 转移指针,支持带右值得拷贝赋值,支持参数传递拷贝构造的,他的左值的拷贝构造也是被关闭了 看下图