[英]Basic posix thread argument passing issue
我正在嘗試進入線程世界,但遇到了一些麻煩。 下面的代碼每隔一段時間工作一次,但似乎是完全隨機的。 給它相同的輸入會不斷給我不同的結果,我很困惑。 有時 PrintHello() 打印出參數,有時打印垃圾,有時只是段錯誤。
#define NUM_THREADS 5
char *prompt = "% ";
struct thread_data{
int thread_id;
//int sum;
char *message;
};
void *PrintHello(void *threadarg)
{
struct thread_data *local_data;
local_data = (struct thread_data *) threadarg;
int taskid = local_data->thread_id;
const char *arguments = local_data->message;
fprintf(stderr, "Hello World! It's me, thread %s!\n", arguments);
pthread_exit(NULL);
}
PrintHello() 是我認為問題所在。
int main()
{
int pid;
//int child_pid;
char line[81];
char *token;
char *separator = " \t\n";
char **args;
char **args2;
char *hp;
char *cp;
char *ofile;
int i;
int j, h, t, rc;
args = malloc(80 * sizeof(char *));
args2 = malloc(80 * sizeof(char *));
signal(SIGINT, SIG_IGN);
while (1) {
fprintf(stderr, "%s", prompt);
fflush(stderr);
if (fgets(line, 80, stdin) == NULL)
break;
/* get rid of the '\n' from fgets */
if (line[strlen(line) - 1] == '\n'){
line[strlen(line) - 1] = '\0';
}
// split up the line
i = 0;
while (1) {
token = strtok((i == 0) ? line : NULL, separator);
if (token == NULL)
break;
args[i++] = token;
}
args[i] = NULL;
ofile = args[i-1];
printf("%s\n", ofile);
上面的東西只是標記輸入並且工作正常。
struct thread_data thread_data_array[i];
pthread_t threads[i];
for(t=0; t<i; t++){
thread_data_array[t].thread_id = t;
thread_data_array[t].message = args[t];
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&thread_data_array[t]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
}
}
您的代碼有幾個問題,但我將重點討論影響穩定性的關鍵問題。
malloc()
的返回值。 如果返回值為 NULL,則表示操作失敗,您必須重試,或開始從malloc()
、 calloc()
、 strdup()
等清除所有動態分配的內存,並完成您的優雅地編程。 嘗試取消引用 NULL(即:使用來自失敗的內存分配調用的指針)將使您的程序崩潰。'\\0'
,然后繼續。while
循環立即再次執行,並將新值重新分配給thread[]
數組。 此外,相同的參數在仍在使用時傳遞給它們( thread_data_array[t]
),並且您沒有互斥體來保護它們。 此外,如果您的程序的main()
提前退出,那么所有正在運行的線程都會立即被終止,並且無法完成。pthread_join()
以確保在繼續之前等待它們完成。gcc test.c -lpthread -O0 -ggdb
編譯它,然后在使用run
在 gdb 中啟動它后通過“next” n
命令逐步執行代碼。 它讓你的生活輕松很多。#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#define NUM_THREADS 5
#define BUF_LEN (80)
char *prompt = "% ";
struct thread_data{
int thread_id;
//int sum;
char *message;
};
void *PrintHello(void *threadarg)
{
struct thread_data *local_data;
local_data = (struct thread_data *) threadarg;
int taskid = local_data->thread_id;
const char *arguments = local_data->message;
fprintf(stderr, "Hello World! It's me, thread %s!\n", arguments);
pthread_exit(NULL);
}
int main()
{
int pid;
//int child_pid;
char line[81];
char *token;
char *separator = " \t\n";
char **args;
char **args2;
char *hp;
char *cp;
char *ofile;
int i;
int j, h, t, rc;
args = malloc(BUF_LEN * sizeof(char *)); // ISSUE: Can fail. Check return value.
args2 = malloc(BUF_LEN * sizeof(char *)); // ISSUE: Can fail.
signal(SIGINT, SIG_IGN);
while (1)
{
fprintf(stderr, "%s", prompt);
fflush(stderr);
if (fgets(line, BUF_LEN, stdin) == NULL)
{
break;
}
/* get rid of the '\n' from fgets */
/*
if (line[strlen(line) - 1] == '\n'){
line[strlen(line) - 1] = '\0';
}
*/
for ( t = 0; t < BUF_LEN; t++ )
{
if ( line[t] == '\n' )
{
line[t] = '\0';
}
}
// split up the line
i = 0;
int numTokens = 0;
while (1) {
token = strtok((i == 0) ? line : NULL, separator);
if (token == NULL)
{
break;
}
args[i++] = token;
numTokens++;
}
// Abort if zero tokens found.
if ( numTokens == 0 )
{
continue;
}
// Exit if input is "quit"
if ( strcasecmp(line, "quit") == 0 )
{
break;
}
args[i] = NULL;
ofile = args[i-1];
printf("%s\n", ofile);
struct thread_data thread_data_array[i];
pthread_t threads[i];
for(t=0; t<i; t++)
{
thread_data_array[t].thread_id = t;
thread_data_array[t].message = args[t];
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&thread_data_array[t]);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
// Wait for threads to complete work.
for(t=0; t<i; t++)
{
pthread_join(threads[t], NULL);
}
}
}
%
%
%
% Hello world. This is a test
test
Hello World! It's me, thread test!
Hello World! It's me, thread a!
Hello World! It's me, thread is!
Hello World! It's me, thread This!
Hello World! It's me, thread world.!
Hello World! It's me, thread Hello!
%
% 1 2 3
3
Hello World! It's me, thread 3!
Hello World! It's me, thread 2!
Hello World! It's me, thread 1!
% QUit
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.