【题目1】
子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码
【题解】
首先我们来分析一下这道题...(是个刚入门的小白,分析的不好请见谅)
1、由于子线程需要循环10次不受主线程干扰,而主线程需要循环100次不受子线程干扰,所以显然,在他们进入循环的时候需要一个锁把这段循环锁住,不然会导致资源被抢占(此处的资源可以理解为是循环里的cout)。(其实简单来说互斥量是为了保证子线程和主线程的for不同时进行)
2、然后问题来了,怎么控制子线程循环后主线程循环,然后一直这样依次循环呢?条件变量就可以做到这点,我们可以通过改变某个全局变量的值,第一次将该全局变量置为10,也就是说我们只要控制如果传入的参数和该全局变量不等,就让他一直等待,当执行完子线程的循环后改变这个全局变量为100,那么对于子线程来说全局变量和传入的参数就不相等了,那么条件变量就会一直等待。当然如果一直让他等待肯定是不对的,所以当一个线程执行完循环之后需要唤醒这个条件变量,告诉线程变量已经改变又可以开始抢资源啦。(其实条件变量就是为了控制子主线程运行的先后条件)
【代码】
#include<thread> #include<iostream> #include<cstdio> #include<mutex> #include<condition_variable> using namespace std; int flag = 10; mutex mu; condition_variable cv; void fun(int x, char c) { for (int i = 0; i < 50; i++) { unique_lock<mutex> lock(mu); while(flag != x) cv.wait(lock);//在该线程阻塞之前会执行lock.unlock,这样别的线程才不会被锁住 for (int j = 0; j < x; j++) cout << c << ":" << j << endl; flag = (x == 10)? 100 : 10; cv.notify_one(); } } int main() { thread t1(fun, 10, 'A'); fun(100, 'B'); t1.join(); }