看这样一个函数(其中i,sum为全局变量):
#includeusing namespace std; int i=0; int sum = 0; void func() { i++; for (int j = 0; j < 10; ++j) { cout << j << ' '; } sum += i; } int main(){ func(); cout< 直接调用fuc(),结果为(如果这个结果看不懂,可以从头开始学cpp了):
加入多线程的写法
我这里是vs2019,库是thread。只需要实例化一个thread,并且将函数指针传进去即可(带参的问题可以自己查文档吧,下次修改再补充)。
启动目前看了两种方式,join就是阻塞主线程(即join的线程运行完了,主线程才会继续),detach不阻塞主线程。#include#include using namespace std; int i=0; int sum = 0; void func() { i++; for (int j = 0; j < 10; ++j) { cout << j << ' '; } sum += i; } int main(){ thread thread1(func); thread thread2(func); thread thread3(func); thread1.join(); thread2.join(); thread3.join(); cout< 这里采用了3个线程,我们期望是3个0-9的输出+一个sum=6的输出。
但是,就目前来说,这个函数的输出结果是不可预料的。
输出结果(3次)
如果3个都是detach而不是join的话thread1.detach(); thread2.detach(); thread3.detach();结果也是不可预料的,但是可以肯定的是,3个子线程不可能执行完的。大概率直接输出一个0.
mutex线程同步
如果其中2个都是detach,即有一个为join。给出一次结果:
原因主函数要等join完以后才会输出sum的值,然后return 0,至于detach搞完没有,主函数不管。
不管怎样,我们期望的sum应该是1+2+3=6,而不是3个join大概率的9,以及3个detach的0,一个join的3或者其他。下面用mutex互斥量来解决这个问题。#include#include #include using namespace std; mutex mu; int i=0; int sum = 0; void func() { mu.lock(); i++; for (int j = 0; j < 10; ++j) { //第一个输出 mu.lock(); cout << j << ' '; //第一个输出 mu.unlock(); } sum += i; mu.unlock(); } int main(){ thread thread1(func); thread thread2(func); thread thread3(func); thread1.join(); thread2.join(); thread3.join(); cout< 第一次的互斥量,保证了序列化
第一次的互斥量,保证了结果的正确性
互斥量使得这段代码变成了串行了。所以mutex加锁的代码应该越短越好(长了的话,就没必要多线程了呀)。本例去掉中间的for循环的话,更加适合mutex加锁的实际应用场景。
但是这样写的好处有:
1.拉长运行时间,使得结果出现不一样的概率增大,便于写稿子233333。
2.比较i,j能理解线程间共享什么,不共享什么。
3.mu互斥量守护的代码的功能。声明:本稿是学习稿,如描述存在问题,还望各位读者批评指正。



