【问题标题】:Why garbage is displayed in the thread function? | Pthread [closed]为什么线程函数中显示垃圾? | Pthread [关闭]
【发布时间】:2020-05-03 15:32:57
【问题描述】:

对不起我的英语。 我正在使用 QT Creator。 我刚刚开始研究线程)这是我的第一个严重问题。 我不明白为什么我无法从线程函数中获取字符串的确切值。

With string

My code

Output

我尝试了很多选择,但一切都是徒劳的。 我试图做 'char *' 而不是 'string' ...尝试构建结构,但仍然无法正常工作。

with struct

#include <iostream>
#include <pthread.h>
#include <string>
#include <cstring>

#define NUM_THREAD 4

using namespace std;

struct message_info {
    char* message;
};

void *PrintMessage(void *arg) {
    message_info *new_info;
    new_info = (struct message_info*)arg;
    pthread_t id = pthread_self();
    cout << "ID thread :" << id << new_info->message << endl;
    pthread_exit(NULL);
}

int main(){
    pthread_t id_stream[NUM_THREAD];
    for (int i = 0; i < NUM_THREAD; i++){
        struct message_info call_mess;
        call_mess.message = "This is messaf";
        int rec = pthread_create(id_stream, NULL, PrintMessage, (void *)&call_mess);
        if (rec != 0) {
            cout << "Error: Thread not created | " << rec << endl;
            exit(-1);
        }
    }
    pthread_exit(NULL);
}

【问题讨论】:

  • 欢迎来到 SO。请将您的代码添加到问题中。跟随外部资源的链接是大多数人不想做的事情。此外,由于代码只是文本,无需将其显示为艺术品。只需将代码和任何纯文本输出复制并粘贴到问题中即可。这将大大增加响应。
  • 你的代码是 C++ 而不是 C。
  • 你将一个指向局部变量的指针传递给线程。当线程开始访问它时,变量已经被破坏的可能性很高。您的程序通过数据竞争表现出未定义的行为。
  • 为什么要直接使用 pthreads 而不是std::thread 和朋友?另外,请记住,您需要对从多个线程访问的变量进行同步。然后是@Igor 提到的终身问题。
  • 非常感谢大家 =) 我很高兴我明白为什么会发生这种情况。也许这个问题会用'pthread_join'解决

标签: c++ pthreads


【解决方案1】:
int rec = pthread_create(id_stream, NULL, PrintMessage, (void *)&call_mess)

这将创建一个新线程,将指向call_mess 的指针作为PrintMessage 的参数传递给它。

这个,父线程,立即继续运行,它从pthread_create()返回并到达循环的末尾,此时call_mess对象得到被摧毁。 call_mess 仅在 for 循环结束之前存在,此时它在 for 循环再次迭代(或不迭代)之前被销毁。

绝对不能保证新线程将开始运行,将读取它作为参数接收的指针,并将其复制, call_mess 在父线程的循环结束时被销毁之前。 pthread_create 给你的唯一保证是新线程将开始执行。在某个未指定的未来的某个时间,它甚至可能在pthread_create() 返回后还没有运行。但它会运行。某天。一段时间。最终。

所以这里显然发生的是这个call_mess 对象在每个新线程读取它之前就被销毁了。而已。欢迎来到多执行线程的世界。这会导致未定义的行为,以及您看到的随机垃圾结果。

为了正确执行此操作,您将不得不编写更多代码,使用互斥锁和条件变量,以使父线程等待新线程开始执行并获取其参数,并让父线程仅在子线程取出它的参数。

【讨论】:

    猜你喜欢
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 2019-10-04
    相关资源
    最近更新 更多