zoukankan      html  css  js  c++  java
  • 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 }

    运行结果

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

  • 相关阅读:
    mysqldump 导出数据库为DBname的表名为Tname的表结构 导出数据库的所有表的表结构
    mysqldump 备份某张表 Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions,
    nfs missing codepage or helper program, or other error
    date 增加一个小时 减少一个小时
    mysqldump 备份单个数据库
    mysql删除账户
    怎么删除某个用户的所有帖子?
    mongodb删除重复数据
    ReSharper2018破解详细方法
    激活windows和office
  • 原文地址:https://www.cnblogs.com/main404/p/11191892.html
Copyright © 2011-2022 走看看