C++11多线程编程(常见面试题)

【题目1】ios

子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码ide

 

【题解】spa

首先咱们来分析一下这道题...(是个刚入门的小白,分析的很差请见谅)线程

一、因为子线程须要循环10次不受主线程干扰,而主线程须要循环100次不受子线程干扰,因此显然,在他们进入循环的时候须要一个锁把这段循环锁住,否则会致使资源被抢占(此处的资源能够理解为是循环里的cout)。(其实简单来讲互斥量是为了保证子线程和主线程的for不一样时进行code

二、而后问题来了,怎么控制子线程循环后主线程循环,而后一直这样依次循环呢?条件变量就能够作到这点,咱们能够经过改变某个全局变量的值,第一次将该全局变量置为10,也就是说咱们只要控制若是传入的参数和该全局变量不等,就让他一直等待,当执行完子线程的循环后改变这个全局变量为100,那么对于子线程来讲全局变量和传入的参数就不相等了,那么条件变量就会一直等待。固然若是一直让他等待确定是不对的,因此当一个线程执行完循环以后须要唤醒这个条件变量,告诉线程变量已经改变又能够开始抢资源啦。(其实条件变量就是为了控制子主线程运行的前后条件blog

 

【代码】资源

#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(); }
View Code

 

【总结】it

理解这段代码的时候,被wait()弄了很久,多是我太蠢qwq那么来讲一下wait()吧,咱们分两种状况来讲。io

(1)一开始,主线程先抢到了锁入门

那么就会判断flag是否等于x,很显然若是是主线程先拿到锁此时flag=10,x=100不等,那么这个时候主线程就会执行wait(),也就是会被阻塞,而后由于wait()自身有这样一个机制(当他执行的时候会自动释放锁吗,也就是会自动执行unlock,给其余线程一个拿锁的机会),这个时候子线程就会拿到锁,而且判断fag是否等于x,这时候明显是相等的,那么就会进行下面的一系列循环,这个时候重点来了,必定要改变全局变量!!若是不改变会是什么结果呢?假设咱们把那句话注释掉直接执行notify_one(),那么主线程就会被唤醒它的wait()又会自动参与抢锁,因为flag没有改变,那么flag和x的值仍是相等,因此它依然会被阻塞,那么依旧就是子线程执行,就不知足题意了。

(2)一开始,子线程先抢到了锁

由于知足flag=x,那么会执行接下来的for,循序渐进改个flag,而后唤醒被wait的线程(这时候其实没有),由于执行完一个循环,uniqie_lock会自动释放锁,而后子线程和主线程就又开始抢锁了,此次咱们假设仍是子线程先抢到了锁,但因为修改了flag,此时flag!=x,子线程就被阻塞,而后就和状况(1)差很少啦。

 

 

 

 

【题目2】

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每一个线程将本身的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

 

【题解】

其实只要理解了上一题,就是一个套路啦。这里有所不一样的是有3个线程,因此最后唤醒条件变量的时候记得用notify_all()。

 

【代码】

#include<thread> #include<iostream> #include<cstdio> #include<mutex> #include<condition_variable>
using namespace std; int flag = 0; mutex mu; condition_variable cv; void fun(int x) { for (int i = 0; i < 10; i++) { unique_lock<mutex>lock(mu); while (x != flag) cv.wait(lock); cout << static_cast<char>('A' + x) << " "; flag = (flag + 1) % 3; cv.notify_all(); } } int main() { thread t1(fun, 1); thread t2(fun, 2); fun(0); t1.join(); t2.join(); }
View Code
相关文章
相关标签/搜索