C++并行开发4-创建多个线程,数据共享问题分析

FengLY Lv3

1.创建多个线程

#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
using namespace std;

void myprint(int i) {
    cout << "第 " << i << "个线程开始运行" << endl;

    cout << "第 " << i << "个线程运行结束" << endl;
}


int main()
{
    vector<thread> mythreads;

    for (int i = 0; i < 10; i++) {
        mythreads.push_back(thread(myprint, i));
    }

    for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) {
        iter->detach();
    }

    cout << "主线程运行结束" << endl;
    return 0;
}

2 数据共享问题

2.1 只读数据

#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
using namespace std;

vector<int> g_v = { 1, 2, 3 };  //这种创建方法是C++11新特性

void myprint(int i) {
    cout << "第 " << i << "个线程开始运行" << endl;

    cout << "线程ID为" << std::this_thread::get_id() << "打印" << g_v[0] << g_v[1] << g_v[2] << endl;

    cout << "第 " << i << "个线程运行结束" << endl;
}


int main()
{
    vector<thread> mythreads;

    for (int i = 0; i < 10; i++) {
        mythreads.push_back(thread(myprint, i));
    }

    for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) {
        iter->join();
    }

    cout << "主线程运行结束" << endl;
    return 0;
}

只读数据是安全的

2.2 有读有写的数据

  • 若不加处理,就会出错

  • 最简单的防止崩溃方法:读的时候不能写,写的时候不能读。

  • 写的动作分10小步,由于任务切换,导致各种诡异的事情发生(最可能的还是崩溃)

    #include
    #include
    #include
    #include
    #include
    using namespace std;

    //调用类对象的成员函数的方式来创建线程

    class A {
    public:
    void inMsgRecvQueue()
    {
    for (int i = 0; i < 10000; i++) {
    cout << “消息队列插入一个元素 “ << i << endl;
    msgRecvQueue.push_back(i);
    }
    }

    void outMsgRecgQueue() {
    for (int i = 0; i < 10000; i++) {
    if (!msgRecvQueue.empty()) {
    //消息队列非空
    int command = msgRecvQueue.front(); //取出第一个元素
    msgRecvQueue.pop_front();
    }
    else {
    //消息队列为空
    cout << “outMsgRecgQueue执行,目前消息队列为空” << endl;
    }
    }
    }
    private:
    list msgRecvQueue; //消息队列
    };

    int main()
    {
    A myobja;
    std::thread myOutnMsgObj(&A::outMsgRecgQueue, &myobja);
    std::thread myInnMsgObj(&A::inMsgRecvQueue, &myobja);

    //这里必须使用引用,否则线程会重新拷贝构造一个对象,
    //但是使用引用就需要考虑类对象的使用周期,必须在主线程使用结束

    myOutnMsgObj.join();
    myInnMsgObj.join();

    return 0;
    }


程序会出现有读有写的过程

  • Title: C++并行开发4-创建多个线程,数据共享问题分析
  • Author: FengLY
  • Created at : 2023-06-18 22:40:09
  • Updated at : 2023-06-18 22:55:54
  • Link: https://zhouaq.com/2023/06/18/C++并行开发4-创建多个线程,数据共享问题分析/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
C++并行开发4-创建多个线程,数据共享问题分析