在不同线程中运行的函数会产生奇怪的输出

问题描述:

你好,我是C++多线程新手。我正在使用C++ 11中提供的线程类,以便在不同的线程中运行函数,但不知何故,从函数获得的输出非常尴尬。这可能是因为不同的线程可能试图同时执行相同的变量,从而导致冲突。请建议我应该如何修改我的代码,以便我可以得到正确的输出。我发布了一个我正在尝试做的示例代码。这不是原始代码,但它只是显示我的原始代码的流程,因为我的原始代码太长而无法发布,但问题在两种情况下都保持不变。在不同线程中运行的函数会产生奇怪的输出

#include<iostream> 
    #include<thread>  

    using namespace std; 

    typedef struct { 
     int thread_id; 
     char *message; 
    }threadData; 

    int display(threadData *tData){ 
     threadData *my_data; 
     my_data = (threadData *) tData; 

     cout << "Thread ID: " << my_data -> thread_id << endl; 
     cout << "Message: " << my_data -> message << endl; 

     return 0; 
    } 

    int main(){ 

     threadData *data; 

     data = (threadData *)malloc(sizeof(threadData)); 
     data->thread_id = 12; 
     data->message = "This is the message"; 
     for (int i = 0; i<10; i++) 
     { 
      std::thread t1(display, data);  
      t1.detach(); 
     } 
     return 0; 
    } 

输出:

Thread ID: 12 
    Message: This is the messageThread ID: 
    12 
    Message: This is the message 
    Thread ID: 12 
    Message: This is the message 
    Thread ID: 12 
    Message: This is the message 
    Thread ID: 12 
    Message: This is the message 
+1

您想了解锁定和内存模型。认真:这是一个非常广泛的话题;你不应该去“举例”;但“按概念”。含义:研究这个话题;例如通过在网上搜索“C++线程锁定示例”。我的意思是:是的,当人们向你解释一些东西的时候很好。但这些东西被记录了数十亿次;而不是写出这个问题,你会花费更少的时间来搜索网络。请注意:这仍然是一个有效的问题,所以没有downvote或近距离投票,但仍然... – GhostCat

+1

确实,阅读有关锁定和一般线程概念。另外,'malloc'和'C++'? 'typedef struct'?您可能也想梳理一下C++。 –

由于线程不guaruntee先运行, 你需要保护访问共享资源。 最简单的方法是通过互斥锁。

std::mutex g_i_mutex; // protects g_i 

typedef struct { 
    int thread_id; 
    string message; 
}threadData; 

int display(threadData *tData) 
{ 
std::lock_guard<std::mutex> lock(g_i_mutex); 
threadData *my_data; 
my_data = (threadData *) tData; 

cout << "Thread ID: " << my_data -> thread_id << endl; 
cout << "Message: " << my_data -> message << endl; 

return 0; 

}

输出:

线程ID:12 消息:这是消息 线程ID:12 消息:这是消息 线程ID:12 消息:这是信息 螺纹编号:12 信息:这是信息

我建议你多阅读一些关于线程概念。背后的概念并不简单,只是获得一个现成的解决方案从长远来看不会对您有所帮助。

我读的是for循环预期运行10次,但它只运行了4次,原因是因为在主函数中没有等待所有线程完成,所以主进程退出之前线程有机会运行。 '主'需要睡一会儿等待所有线程完成他们的工作。

而我在这里没有看到竞争条件,因为所有线程只是读取,没有人写入threadData。