c++多线程编程互斥锁初步

上一次讲述了多线程编程,但是由于线程是共享内存空间和资源的,这就导致:在使用多线程的时候,对于共享资源的控制要做的很好。先上程序:

 1 #include <iostream>
 2 #include <thread>
 3 #include <chrono>
 4 #include <mutex>
 5 
 6 using namespace std;
 7 
 8 mutex mtx;
 9 
10 void fn1()
11 {
12     for (int i = 0; i < 5; i++)
13     {
14         mtx.lock();
15         cout << "线程" << this_thread::get_id() << ":" << "The thread1 is running !" << endl;
16         mtx.unlock();
17     }
18 }
19 
20 void fn2()
21 {
22     for (int i = 0; i < 5; i++)
23     {
24         mtx.lock();//锁住的是什么资源,什么时候加锁?
25         cout << "线程" << this_thread::get_id() << ":" << "The thread2 is running !" << endl;
26         mtx.unlock();
27     }
28 }
29 
30 int main()
31 {
32     thread t1(fn1);
33     thread t2(fn2);
34     t1.detach();//this_thread是否表示当前进行,而这里的当前进程是否是main函数所在进程
35     t2.detach();
36     this_thread::sleep_for(chrono::milliseconds(1000));//sleep_for表示当前进行休眠一段时间,不与其他进程竞争CPU 
37     cout << "主线程端口:" << this_thread::get_id() << endl;
38     getchar();
39     return 0;
40 }

上面一段程序,在main进程中创建了两个子线程t1,t2。对各个子线程的cout输出流进行了加锁,完了又对锁进行了释放。

其结果如下:

 

 可见:线程t1,t2是交替执行的(这是由CPU时间片轮换造成的?)。假如我们不对cout输出流加锁,我们看看代码:

 1 #include <iostream>
 2 #include <thread>
 3 #include <chrono>
 4 #include <mutex>
 5 
 6 using namespace std;
 7 
 8 mutex mtx;
 9 
10 void fn1()
11 {
12     for (int i = 0; i < 5; i++)
13     {
14         //mtx.lock();
15         cout << "线程" << this_thread::get_id() << ":" << "The thread1 is running !" << endl;
16         //mtx.unlock();
17     }
18 }
19 
20 void fn2()
21 {
22     for (int i = 0; i < 5; i++)
23     {
24         //mtx.lock();//锁住的是什么资源,什么时候加锁?
25         cout << "线程" << this_thread::get_id() << ":" << "The thread2 is running !" << endl;
26         //mtx.unlock();
27     }
28 }
29 
30 int main()
31 {
32     thread t1(fn1);
33     thread t2(fn2);
34     t1.detach();//this_thread是否表示当前进行,而这里的当前进程是否是main函数所在进程
35     t2.detach();
36     this_thread::sleep_for(chrono::milliseconds(1000));//sleep_for表示当前进行休眠一段时间,不与其他进程竞争CPU 
37     cout << "主线程端口:" << this_thread::get_id() << endl;
38     getchar();
39     return 0;
40 }

(就是单纯的注释掉了加锁)。

结果如下:

 

 可以看到,结果产生了紊乱,分析一下这个结果:

线程t1才执行了一点:刚输出完“线程”两个字,转到线程2执行了,接下来再输出了线程t1的内容(并不是跑回去执行线程t1),再去执行线程t1.

造成这种紊乱的原因是:

cout本质上是一个输出流对象,相当于一个公共接口,这个接口是一个公共资源。这里就涉及到了资源共享的问题!!!

所以要对cout这个共享资源加锁!!!这样等当前的输出流执行完,才会到下一个线程!!

posted @ 2019-08-30 11:37  少年π  阅读(2934)  评论(0编辑  收藏  举报