C++多线程基础学习笔记(四)

一、创建多个子线程

前面三章讲的例子都是只有一个子线程和主线程,然而实际中有多个子线程。那么下面介绍如何创建多个子线程。

 1 #include <iostream>
 2 #include <vector>
 3 #include <list>
 4 #include <thread>
 5 using namespace std;
 6 
 7 void mythread(int i)
 8 {
 9     cout << "id为" << std::this_thread::get_id() << "的线程" << endl;
10     cout << "i=" << i << endl;
11     return;
12 }
13 
14 int main()
15 {
16     vector<thread> mythreads;
17     for (int i = 0; i < 10; i++)
18     {
19         mythreads.push_back(thread(mythread, i));  //创建是10个线程并放入容器中
20     }
21     for (auto ite = mythreads.begin(); ite != mythreads.end(); ++ite)
22     {
23         ite->join();      //主线程等待10个线程执行完
24     }
25     cout << "主线程执行完毕" << endl;
26     system("pause");
27     return 0;
28 }

运行结果

可以看出,虽然所有子线程执行完了才到主线程,但各个子线程的执行期间是乱的,没有谁等谁。那么就会引发一个数据共享的问题。

二、数据共享问题

如果多个线程之间知识单纯的读取数据,那么程序是不会出现奔溃等严重问题的,是安全稳定的。但如果既读数据又写数据,程序很有可能崩溃。比如有5个线程,2个线程写数据,3个线程读取同样的数据,试想如果写数据的线程还没写入数据,其他线程就进行读数据操作了,那么必然会出现问题。下面举一个例子说明。

 1 #include <iostream>
 2 #include <vector>
 3 #include <list>
 4 #include <thread>
 5 using namespace std;
 6 //队列,先进先出
 7 class A 
 8 {
 9 private:
10     list<int> msg;
11 public:
12     //把数据写入队列
13     void inMsgRecv()
14     {
15         for (int i = 0; i < 10000; i++)
16         {
17             cout << "插入一个元素" << i << endl;
18             msg.push_back(i);
19         }
20     }
21     //从队列读数据
22     void outMsgRecv()
23     {
24         for (int i = 0; i < 10000; i++)
25         {
26             if (!msg.empty())
27             {
28                 int GetMsg = msg.front();   //接受消息队列的首部
29                 msg.pop_front();            //移除首部
30                 //....然后可以对GetMsg进行你想要的操作
31                 //cout << "GetMsg:" << GetMsg << endl;
32             }
33             else
34             {
35                 cout << "没有数据可读" << endl;
36             }
37         }
38     }
39 };
40 
41 int main()
42 {
43     A myobj;
44     //以成员函数作为线程函数,第一个&是取地址,第二个&是引用
45     thread mythread1(&A::inMsgRecv, &myobj);
46     thread mythread2(&A::outMsgRecv, &myobj);
47     mythread1.join();
48     mythread2.join();
49     system("pause");
50     return 0;
51 }

运行结果

那么要处理多线程的数据共享问题,就要涉及一个概念“互斥量”,下面一章将会讲到。

posted @ 2019-07-15 22:07  main(0)  阅读(387)  评论(0编辑  收藏  举报