为什么线程函数中显示垃圾? |线程
Why garbage is displayed in the thread function? | Pthread
对不起我的英语。
我正在使用 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);
}
int rec = pthread_create(id_stream, NULL, PrintMessage, (void *)&call_mess)
这将创建一个新线程,将指向 call_mess
的指针作为参数传递给它 PrintMessage
。
这个,父线程,立即继续运行ning,它returns来自pthread_create()
并到达循环的末尾,此时 call_mess
对象被销毁。 call_mess
只存在于 for
循环结束之前,此时它在 for
循环再次迭代(或不迭代)之前被销毁。
你绝对不能保证新线程将启动运行ning,将读取它的指针作为参数接收,并将在 call_mess
在父线程的循环结束时被销毁之前复制它。 pthread_create
给你的唯一保证是新线程将开始执行。在某个未指定的未来某个时间,甚至可能在 pthread_create()
returns 之后 运行ning。但它会运行。有一天。一些时间。终于。
所以这里明显发生的是这个 call_mess
对象在每个新线程读取它之前就被销毁了。而已。欢迎来到多执行线程的世界。这会导致未定义的行为,以及您看到的随机垃圾结果。
为了正确地做到这一点,您将不得不编写更多的代码,使用互斥锁和条件变量,让父线程等待直到新线程开始执行并获取它的参数,并且让父线程只恢复执行子线程取出参数后
对不起我的英语。 我正在使用 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);
}
int rec = pthread_create(id_stream, NULL, PrintMessage, (void *)&call_mess)
这将创建一个新线程,将指向 call_mess
的指针作为参数传递给它 PrintMessage
。
这个,父线程,立即继续运行ning,它returns来自pthread_create()
并到达循环的末尾,此时 call_mess
对象被销毁。 call_mess
只存在于 for
循环结束之前,此时它在 for
循环再次迭代(或不迭代)之前被销毁。
你绝对不能保证新线程将启动运行ning,将读取它的指针作为参数接收,并将在 call_mess
在父线程的循环结束时被销毁之前复制它。 pthread_create
给你的唯一保证是新线程将开始执行。在某个未指定的未来某个时间,甚至可能在 pthread_create()
returns 之后 运行ning。但它会运行。有一天。一些时间。终于。
所以这里明显发生的是这个 call_mess
对象在每个新线程读取它之前就被销毁了。而已。欢迎来到多执行线程的世界。这会导致未定义的行为,以及您看到的随机垃圾结果。
为了正确地做到这一点,您将不得不编写更多的代码,使用互斥锁和条件变量,让父线程等待直到新线程开始执行并获取它的参数,并且让父线程只恢复执行子线程取出参数后