当前位置:   article > 正文

C++11多线程部分知识点 + 多线程顺序执行 + 交替打印字符串_c++线程加锁执行顺序

c++线程加锁执行顺序
  • 之前在Linux下操作C的API pthread相关函数 写多线程,或者使用Qt的QThread实现多线程编程,不太具备通用性
  • C++11相较于C++98添加了蛮多的多线程编程的特性,本文记录下其中部分知识。

1. 基础知识

C++ 多线程编程入门基础: 学习链接
C++并发编程 - 同步并发操作:添加链接描述

2. 按序打印

代码解法类似 1.基础知识 里面的最后一个案例
在这里插入图片描述

class Foo {
public:
    Foo() {
    }
    void first(function<void()> printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        flag1 = true;
        cv.notify_all();
    }

    void second(function<void()> printSecond) {
        unique_lock<mutex> loc(m);
        while(flag1==false){
            cv.wait(loc);
        }
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        flag2 = true;
        cv.notify_all();
    }

    void third(function<void()> printThird) {
        unique_lock<mutex> loc(m);
        while(flag2==false){
            cv.wait(loc);
        }
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
private:
    mutex m;
    condition_variable cv;
    bool flag1 = false;
    bool flag2 = false;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

3.交替打印FooBar

在这里插入图片描述在这里插入图片描述

condiation_variable的wait方法有两种:有条件的等待和无条件的等待
wait有条件等待与无条件等待
在这里插入图片描述

class FooBar {
private:
    int n;
    mutex mtx;
    condition_variable cv;
    bool foo_done=false;
public:
    FooBar(int n) {
        this->n = n;
    }
    void foo(function<void()> printFoo) {
        for (int i = 0; i < n; i++) {
            unique_lock<mutex> locker(mtx);
            while(foo_done==true)
                cv.wait(locker);
            // cv.wait(locker,[&](){return foo_done==false;})
            printFoo();
            foo_done=true;
            cv.notify_one();
        }
    }
    void bar(function<void()> printBar) {
        for (int i = 0; i < n; i++) {
            unique_lock<mutex>locker(mtx);
            while(foo_done==false)
                cv.wait(locker);
            //cv.wait(locker,[&](){return foo_done==true;})  除了while还可以采用条件wait
            printBar();
            foo_done=false;
            cv.notify_one();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

4. 汇总


/*************************
example1 - join :
	main是主线程,t1是主线程中的子线程,在这个线程里执行函数fun1()。
	使用join()函数,那么主线程就会一直阻塞在t1.join();的位置,直到子线程t1运行结束后,再接着执行后面的语句。

	fun1()函数里写了一个休眠1s的语句,所以t1线程在还没有打印fun1的时候,主线程由于没有写join()函数阻塞起来,就会继续往后执行,先打印出main,等t1休眠了1s后,才打印出fun1。
	join()函数除了阻塞作用,另一个作用就是回收该线程使用到的资源,上面的程序把join()删掉了,子线程t1的资源不能正确回收,程序运行会报错“abort() has been called”。
**************************/
#if 0



#include<iostream>
#include <thread>
#include <chrono>

using namespace std;

void ff() {
	cout << "func1" << endl;
	this_thread::sleep_for(chrono::seconds(1));
}


int main()
{
	thread t1(ff);
	//t1.join();
	cout << "main" << endl;
	return 0;
}

#endif

/*************************
example2 - detach :
	 那如果子线程t1的运行时间太长了,我不想让主线程阻塞等待t1运行,怎么办呢?下面就介绍detach()函数。
	 detach()函数的作用是将子线程和主线程分离,让子线程在后台独立运行。如果主线程运行很快,先结束运行了,子线程还未执行完的话,那么子线程会在后台继续执行,执行完毕时由线程库回收其资源。
	 请看如下例子,主线程中创建子线程t1,通过detach()函数,t1从主线程中分离并开始运行,输出fun1()开始 ,然后休眠1s,这个过程中主线程输出main(),然后子线程休眠结束,输出fun1()结束。
**************************/

#if 0
#include<iostream>
#include <thread>
#include <chrono>

using namespace std;

void fun1() {
	cout << "fun1()开始" << endl;
	this_thread::sleep_for(chrono::seconds(1));  // 休眠1秒
	cout << "fun1()结束" << endl;
}

int main() {
	thread t1(fun1);    // 创建一个线程,名为t1,这个线程会执行fun1()函数
	t1.detach();
	this_thread::sleep_for(chrono::milliseconds(500));  // 休眠0.5秒
	cout << "main()" << endl;
	system("pause");
}


#endif



/*************************
example3 - 互斥锁mutex :
	- lock_guard   没有lock和unlock接口,靠析构函数自动释放,作用域是局部空间 粒度较大
	- unique_lock  有lock和unlock的接口,可以锁定代码段,粒度更小

**************************/

#if 0

#include<iostream>
#include <thread>
#include <mutex>
#include <chrono>

using namespace std;

mutex m;

void fun1() {
	lock_guard<mutex>  loc(m);	// 构造函数里自动加锁
	cout << "fun1" << endl;     // 做别的事情
	// lock_guard出了这个作用域,自动解锁
}

void fun2() {
	unique_lock<mutex>  loc(m);	// 构造函数里自动加锁
	cout << "do A" << endl;
	loc.unlock();			    // 解锁

	loc.lock();		            // 重新加锁
	cout << "do B" << endl;
	loc.unlock();				// 解锁
}

int main() {
	thread t1(fun2);    // 创建一个线程,名为t1,这个线程会执行fun1()函数
	t1.detach();
	this_thread::sleep_for(chrono::milliseconds(500));  // 休眠0.5秒
	cout << "main()" << endl;
	system("pause");
}


#endif

/*************************

example4 - 条件变量condition_variable :
	 上述的unique_lock通常是和condition_variable配合使用的。当 condition_variable 对象的 wait() 函数被调用的时候,它使用 unique_lock来锁住当前线程。
	 当前线程会一直被阻塞,直到另外一个线程在相同的 condition_variable 对象上调用了notification()函数来唤醒当前线程。

**************************/

#if 0

/*
//原始版本  线程顺序容易出错

#include<iostream>
#include <thread>
#include <mutex>
#include <chrono>

using namespace std;

mutex m;

class Foo {
public:
	Foo() {}

	void first() {
		for (int i = 0; i < 10; ++i) {
			cout << "first" << endl;	// 打印10个first
		}
	}

	void second() {
		for (int i = 0; i < 10; ++i) {
			cout << "second" << endl;  // 打印10个second
		}
	}

	void third() {
		for (int i = 0; i < 10; ++i) {
			cout << "third" << endl;  // 打印10个third
		}
	}
};

int main() {
	Foo F;
	// 创建3个线程,分别调用first()、second()、third()函数打印
	thread(&Foo::first, &F).detach();
	thread(&Foo::second, &F).detach();
	thread(&Foo::third, &F).detach();
	system("pause");
}

*/


// 如何让三个线程按序打印,也就是不管哪个线程先被创建,都按照first()、second()、third()的顺序打印呢?

/*
 这时候就可以用前面提到过的unique_lock和condition_variable。我们设置两个标志位,flag1为true表示允许second打印、flag2为true表示允许third打印,先初始化flag1、flag2为false。线程创建后,可能出现以下的执行顺序:
(1)如果在first()还未打印完时(或者压根还没开始执行时),执行second(),由于此时flag1被初始化为false,进入while循环,调用条件变量的wait函数,会将当前线程阻塞起来。此时需要等另一个子线程执行first()打印完毕后,将flag1设为true,然后调用notify_all()将阻塞的线程唤醒,second()才能接着执行,完成打印。
(2)如果first()已经执行完毕,然后执行second(),那么flag1为true,执行second()的那个线程不会进入while循环,也不会被阻塞起来,能顺利执行。
third()的执行先后也可参考以上两种情况。
*/


#include<iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using namespace std;


class Foo {
private:
	mutex m;                      // 互斥锁
	condition_variable cd_v;      // 条件变量
	bool flag1;                   // 两个标志位
	bool flag2;
public:
	Foo() : flag1(false), flag2(false) {}   // 初始化两个标志位为false,表示second和third还不能打印

	void first() {
		for (int i = 0; i < 10; ++i) {
			cout << "first" << endl;
		}
		flag1 = true;        // first执行后,将flag1置为true,表示second可以打印了
		cd_v.notify_all();   // 唤醒等待队列里的所有线程
	}

	void second() {
		unique_lock<mutex> loc(m);	// 加锁
		// (1)先判断flag1是否为true,true则不会进入while循环,顺利向下执行;
		// (2)flag1为false则执行wait函数,释放锁,并进入对象cd_v的等待队列;
		// (3)当别的线程调用对象cd_v的notify_all()函数,会唤醒在等待队列中的这个线程,然后重新获得锁,继续步骤(1)
		while (flag1 == false) {
			cd_v.wait(loc);
		}
		for (int i = 0; i < 10; ++i) {
			cout << "second" << endl;
		}
		flag2 = true;      // 修改flag2表示third已经可以打印了
		cd_v.notify_all(); // 唤醒等待队列里的所有线程
		// 当离开这个局部作用域时,unique_lock会调用析构函数,自动解锁
	}

	void third() {
		unique_lock<mutex> loc(m);
		while (flag2 == false) {
			cd_v.wait(loc);
		}
		for (int i = 0; i < 10; ++i) {
			cout << "third" << endl;
		}
	}
};


int main() {
	Foo F;
	// thread 需要传参,尤其对类对象,函数 + 类对象的地址
	thread t1(&Foo::first, &F);
	thread t2(&Foo::second, &F);
	thread t3(&Foo::third, &F);

	t1.detach();
	t2.detach();
	t3.detach();

	system("pause");
}

#endif // 1



#if 0

//   题目一、交替打印字符串

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <functional>

using namespace std;

class FooBar {
private:
	int n;
	mutex mtx;
	condition_variable cv;
	bool foo_done = false;
public:
	FooBar(int n) {
		this->n = n;
	}
	void foo(function<void()> printFoo) {
		for (int i = 0; i < n; i++) {
			unique_lock<mutex> locker(mtx);
			while (foo_done == true)
				cv.wait(locker);

			printFoo();
			foo_done = true;
			cv.notify_one();
		}
	}
	void bar(function<void()> printBar) {
		for (int i = 0; i < n; i++) {
			unique_lock<mutex>locker(mtx);
			while (foo_done == false)
				cv.wait(locker);
			printBar();
			foo_done = false;
			cv.notify_one();
		}
	}
};


void printBar() {
	cout << "bar" << endl;
}
void printFoo() {
	cout << "Foo" << endl;
}

int main() {
	FooBar F(4);
	// thread 需要传参,尤其对类对象,函数 + 类对象的地址
	thread t1(&FooBar::foo, &F,printBar);
	thread t2(&FooBar::bar,&F,printFoo);

	t1.detach();
	t2.detach();

	system("pause");
}


#endif // 1


#if 1

//   题目一、交替打印字符串

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <functional>

using namespace std;


int n = 5;
mutex mtx;
condition_variable cv;
bool foo_done = false;


void foo(function<void(int)> printFoo) {
	for (int i = 0; i < n; i++) {
		unique_lock<mutex> locker(mtx);
		while (foo_done == true)
			cv.wait(locker);

		printFoo(i);
		foo_done = true;
		cv.notify_one();
	}
}
void bar(function<void(int)> printBar) {
	for (int i = 0; i < n; i++) {
		unique_lock<mutex>locker(mtx);
		while (foo_done == false)
			cv.wait(locker);
		printBar(i);
		foo_done = false;
		cv.notify_one();
	}
}

void printBar(int i) {
	cout << "bar" <<i<< endl;
}
void printFoo(int i) {
	cout << "Foo" <<i<< endl;
}

int main() {
	// thread 需要传参,尤其对类对象,函数 + 类对象的地址
	thread t1(foo, printBar);
	thread t2(bar,printFoo);

	t1.detach();
	t2.detach();

	system("pause");
}


#endif // 1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385

5. 题目2 题目3 可运行代码


// 题目2 多线程顺序执行
#if 0

#include<iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using namespace std;


class Foo {
private:
	mutex m;                      // 互斥锁
	condition_variable cd_v;      // 条件变量
	bool flag1;                   // 两个标志位
	bool flag2;
public:
	Foo() : flag1(false), flag2(false) {}   // 初始化两个标志位为false,表示second和third还不能打印

	void first() {
		for (int i = 0; i < 10; ++i) {
			cout << "first" << endl;
		}
		flag1 = true;        // first执行后,将flag1置为true,表示second可以打印了
		cd_v.notify_all();   // 唤醒等待队列里的所有线程
	}

	void second() {
		unique_lock<mutex> loc(m);	// 加锁
		// (1)先判断flag1是否为true,true则不会进入while循环,顺利向下执行;
		// (2)flag1为false则执行wait函数,释放锁,并进入对象cd_v的等待队列;
		// (3)当别的线程调用对象cd_v的notify_all()函数,会唤醒在等待队列中的这个线程,然后重新获得锁,继续步骤(1)
		while (flag1 == false) {
			cd_v.wait(loc);
		}
		for (int i = 0; i < 10; ++i) {
			cout << "second" << endl;
		}
		flag2 = true;      // 修改flag2表示third已经可以打印了
		cd_v.notify_all(); // 唤醒等待队列里的所有线程
		// 当离开这个局部作用域时,unique_lock会调用析构函数,自动解锁
	}

	void third() {
		unique_lock<mutex> loc(m);
		while (flag2 == false) {
			cd_v.wait(loc);
		}
		for (int i = 0; i < 10; ++i) {
			cout << "third" << endl;
		}
	}
};

int main() {
	Foo F;
	// thread 需要传参,尤其对类对象,函数 + 类对象的地址
	thread t1(&Foo::first, &F);
	thread t2(&Foo::second, &F);
	thread t3(&Foo::third, &F);

	t1.detach();
	t2.detach();
	t3.detach();

	system("pause");
}

#endif


// 题目3  多线程交替打印字符
#if 0



#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <functional>

using namespace std;


int n = 5;
mutex mtx;
condition_variable cv;
bool foo_done = false;

void foo(function<void(int)> printFoo) {
	for (int i = 0; i < n; i++) {
		unique_lock<mutex> locker(mtx);
		while (foo_done == true)
			cv.wait(locker);

		printFoo(i);
		foo_done = true;
		cv.notify_one();
	}
}
void bar(function<void(int)> printBar) {
	for (int i = 0; i < n; i++) {
		unique_lock<mutex>locker(mtx);
		while (foo_done == false)
			cv.wait(locker);
		printBar(i);
		foo_done = false;
		cv.notify_one();
	}
}

void printBar(int i) {
	cout << "bar" <<i<< endl;
}
void printFoo(int i) {
	cout << "Foo" <<i<< endl;
}

int main() {
	// thread 需要传参,尤其对类对象,函数 + 类对象的地址
	thread t1(foo, printBar);
	thread t2(bar,printFoo);

	t1.detach();
	t2.detach();

	system("pause");
}


#endif // 1


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138

6. 题目2题目3 写法2

6.1 三个线程顺序打印


// 三个线程 顺序打印
#if 1
condition_variable cv;
mutex m;
int flag = 0;
int n = 10;

void printA() {
	unique_lock<mutex> loc(m);
	for (int i = 0; i < n; i++){
		cout << "A:" << i << endl;
	}
	flag = 1;
	loc.unlock();
	cv.notify_all();
	
}

void printB() {
	unique_lock<mutex> loc(m);
	while (flag != 1)
		cv.wait(loc);
	for (int i = 0; i < n; i++) {
		cout << "B:" << i << endl;
	}
	flag = 2;
	loc.unlock();
	cv.notify_all();
}

void printC() {
	unique_lock<mutex> loc(m);
	while (flag != 2)
		cv.wait(loc);
	for (int i = 0; i < n; i++) {
		cout << "C:" << i << endl;
	}
	loc.unlock();
	cv.notify_all();
}

int main()
{
	thread t1(printA);
	thread t2(printB);
	thread t3(printC);
	
	t1.detach();
	t2.detach();
	t3.detach();
	system("pause");
	return 0;
}

#endif // 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

6.2 三个线程交替打印


// 三个线程 交替打印
#if 0

condition_variable cv;
mutex m;
int flag = 0;
int n = 10;

void printA() {
	
	for (int i = 0; i < n; i++) {
		unique_lock<mutex> loc(m);
		while (flag != 0) cv.wait(loc);
		cout << "A:" << i << endl;
		flag = 1;
		loc.unlock();
		cv.notify_all();
	}
}

void printB() {

	for (int i = 0; i < n; i++) {
		unique_lock<mutex> loc(m);
		while (flag != 1) cv.wait(loc);
		cout << "B:" << i << endl;
		flag = 2;
		loc.unlock();
		cv.notify_all();
	}
}

void printC() {

	for (int i = 0; i < n; i++) {
		unique_lock<mutex> loc(m);
		while (flag != 2) cv.wait(loc);
		cout << "C:" << i << endl;
		flag = 0;
		loc.unlock();
		cv.notify_all();
	}
}

int main()
{
	thread t1(printA);
	thread t2(printB);
	thread t3(printC);

	t1.detach();
	t2.detach();
	t3.detach();
	system("pause");
	return 0;
}

#endif // 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/197850
推荐阅读
相关标签
  

闽ICP备14008679号