C++多线程编程二

1. 死锁与解锁: 复制代码 #include #include #include using namespace std; //thread引用类型函数,模板,避免类型转换,尽量指针,引用 //锁住一个变量之后,尽快操作完解锁,不要再锁,否则互锁 #define COUNT 100000 mutex g_mutex1, g_mutex2;//互斥量 void add1(int *p1, int *p2) { for (int i = 0; i < COUNT; i++) { /*g_mutex1.lock(); p1++; g_mutex2.lock(); p2++; g_mutex1.unlock(); g_mutex2.unlock();*/ g_mutex1.lock(); (*p1)++; g_mutex1.unlock(); g_mutex2.lock(); (*p2)++; g_mutex2.unlock(); } } void add2(int *p1, int *p2) { for (int i = 0; i < COUNT; i++) { /*g_mutex2.lock(); g_mutex1.lock(); p1++; g_mutex1.unlock(); p2++; g_mutex2.unlock();*/ g_mutex2.lock(); (*p2)++; g_mutex2.unlock(); g_mutex1.lock(); (*p1)++; g_mutex1.unlock(); } } void main() { int a = 0; int b = 0; thread th1(add1, &a, &b); thread th2(add2, &a, &b); th1.join(); th2.join(); while (1) { cout << a << endl; cout << b << endl; this_thread::sleep_for(chrono::seconds(1)); } cin.get(); } 复制代码 2. 迅雷面试题:   编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,   要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。     【参考答案】 复制代码 //编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍, //要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。 #include #include #include #include using namespace std; int LOOP = 10; //循环次数 int flag = 0; //标识符 012012012012 mutex m; condition_variable cv; void fun(int id) { for (int i = 0; i < LOOP; i++) { unique_lock ulk(m); //设定锁定 while ((id-65) != flag) { cv.wait(ulk); //不是该出现的场合,就等待 } cout << (char)id; //转换id flag = (flag + 1) % 3; //012,012,012,... cv.notify_all(); //通知全部 } } void main() { thread t1(fun, 65); thread t2(fun, 66); thread t3(fun, 67); t1.join(); t2.join(); t3.join(); cin.get(); } 复制代码     运行结果:     【分析】若题目变为:4个线程,输出结果要求为: ABCDABCDABCD...又该如何做呢? 复制代码 //编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍, //要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。 #include #include #include #include using namespace std; int LOOP = 10; //循环次数 int flag = 0; //标识符 012012012012 mutex m; condition_variable cv; void fun(int id) { for (int i = 0; i < LOOP; i++) { unique_lock ulk(m); //设定锁定 while ((id-65) != flag) { cv.wait(ulk); //不是该出现的场合,就等待 } cout << (char)id; //转换id flag = (flag + 1) % 4; //012,012,012,... cv.notify_all(); //通知全部 } } void main() { thread t1(fun, 65); thread t2(fun, 66); thread t3(fun, 67); thread t4(fun, 68); t1.join(); t2.join(); t3.join(); t4.join(); cin.get(); } 复制代码     运行结果: 3. 思考:上题中若变为开启5个线程,ID分别为1,2,3,4,5,每个线程将自己的ID在屏幕上打印10遍,要求输出结果为:12345,54321,12345,54321,...依此类推。 4. 线程交换 swap: 复制代码 #include #include using namespace std; void main() { thread t1([]() {cout << "ZhangShan"< #include #include using namespace std; void main() { thread t1([]() { int i = 0; while (1) { i++; if (i > 1000000000) { break; } } cout << i << endl; system("pause"); }); cout << "t1:" << t1.get_id() << endl; //6872 //t1.join(); thread t2 = move(t1);//线程移动,t2具备了t1的属性,t1挂了 cout << "t1:" << t1.get_id() << endl; //0 cout << "t2:" << t2.get_id() << endl; //6872 t2.join(); cin.get(); } 复制代码     运行结果: 6. 线程自动加解锁: 复制代码 #include #include #include using namespace std; #define N 10000000 mutex g_mutex;//全局互斥量 void add(int *p) { for (int i = 0; i < N; i++) { unique_lock ulk(g_mutex); //没有mutex所有权,自动加锁自动解锁,根据块语句锁定 //根据mutex属性来决定,是否可以加锁 //lock_guard lgd(g_mutex); //拥有mutex所有权,自动加锁自动解锁 //读取mutex失败的情况下就会一直等待 (*p)++; } } void main() { int a = 0; thread t1(add, &a); thread t2(add, &a); t1.join(); t2.join(); cout << a << endl; cin.get(); } 复制代码 7. 线程等待固定时间: 复制代码 #include #include #include #include #include #include #include using namespace std; condition_variable cv; mutex m; bool done=false; void run() { auto start = chrono::high_resolution_clock::now(); //当前时间 auto end = start + chrono::seconds(3); unique_lock ulk(m); while (!done) { if (cv.wait_until(ulk, end) == cv_status::timeout)//超时 { done = true; break; } } //this_thread::sleep_until(end); system("pause"); } void main1601() { thread th(run); cin.get(); } void main() { time_t t1, t2; auto start = chrono::high_resolution_clock::now(); //当前时间 t1 = time(&t1); double db = 0; for (int i = 0; i < 1000000000; i++) { db += i; } auto end = chrono::high_resolution_clock::now(); //当前时间 t2 = time(&t2); cout << (end - start).count() << endl; //10^-9秒(ns) cout << difftime(t2, t1) << endl; cin.get(); } 复制代码 8. 多线程实现生产者、消费者: 复制代码 #include #include #include #include #include #include using namespace std; mutex m; condition_variable isfull, isempty;//处理两种情况 bool flag = true;//标志,消费完了就退出 vector myint(10);//开辟10个元素 void produce(int num) //生产 { for (int i = 0; i < num; i++) { unique_lock lk(m); //锁定 while (myint.size()>=10) { isempty.wait(lk); //满了一直等待 } myint.push_back(i);//插入 cout << "生产" << i << endl; isfull.notify_all();//通知消费者 } this_thread::sleep_for(chrono::seconds(5));//休眠5秒 flag = false; } void consume() //消费 { while (flag) { unique_lock lk(m); //锁定 while (myint.size()==0) { isfull.wait(lk);//等待 } if (flag) { cout << "消费" << myint[myint.size() - 1] << " " << this_thread::get_id() << endl; myint.pop_back();//剔除最后一个 isempty.notify_all();//通知生产者继续生产 } } } void main() { thread t1(consume); //消费者 thread t2(consume); thread t3(consume); //produce(100); thread s1(produce,15);//消费者 thread s2(produce,15); t1.join(); t2.join(); t3.join(); cin.get(); }https://www.cnblogs.com/si-lei/p/9515012.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信