为什么同一个 argv[] 在两个线程中打印了两次?
Why is the same argv[] printed twice in the two threads?
我刚开始在多线程中编程并修改一些模板,我生成了这段可能很糟糕的代码:
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
typedef struct __myarg_t //argument struct?
{
int a;
char *b;
} myarg_t;
typedef struct __myret_t //return thread struct?
{
int x;
char *y;
} myret_t;
char cat[100] = ""; //used for concatenation of argv
void *mythread(void *arg)
{
myarg_t *m = (myarg_t *)arg;
int print_index = 0;
printf("THREAD ID: %lu\n", pthread_self());
for (print_index = 0; print_index < m->a; print_index++)
{
printf("Printing %d th character %c\n", print_index, *(m->b + print_index));//spelling the words
}
myret_t *rfin = malloc(sizeof(myret_t));
rfin->x = 1;
strcat(cat, m->b);//concatenating argv with
strcat(cat, " "); //a space to cat
rfin->y = cat;//reassigning the new sentence to rfin
return (void *)rfin;
}
int main(int argc, char *argv[])
{
if (argc == 1)
{
printf("Enter a word as argument before commandline.\nExiting...\n");
exit(0);
}
int rc = 0;
pthread_t p[argc - 1]; //total threads
myret_t *m; //return thread
myarg_t args; //argument thread?
int i = 1;
while (i < argc) //creating threads:
{
printf("THREAD:\t%d\n", i);
args.a = strlen(argv[i]);
args.b = (char *)malloc(strlen(argv[i]));
strcpy(args.b, argv[i]);
pthread_create(&p[i - 1], NULL, mythread, &args);
i++;
}
i = 1;
while (i < argc) // Wait for threads to complete
{
pthread_join(p[i - 1], (void **)&m);
i++;
}
printf("returned %d %s\n", m->x, m->y); //end concatenation result for myret_t *m;
return 0;
}
所以当我执行它时:
gcc -g task2.c -o thread -Wall -pthread
./thread hello there
结果如下:
THREAD: 1
THREAD: 2
THREAD ID: 139848453601024
Printing 0 th character t
Printing 1 th character h
Printing 2 th character e
Printing 3 th character r
Printing 4 th character e
THREAD ID: 139848445208320
Printing 0 th character t
Printing 1 th character h
Printing 2 th character e
Printing 3 th character r
Printing 4 th character e
returned 1 there there
而不是 hello there
。我连接的方式有问题吗?我应该使用另一个线程来做吗?
我是否应该锁定代码的串联部分,因为不同的线程正在同时使用它?
知道我哪里出错了吗?任何 help/advice/criticism 都非常受欢迎。
您的代码中存在竞争条件——您将指向 args
的指针传递给第一个线程,然后 main()
函数立即覆盖对象中的成员变量指针指向,而第一个线程是 运行 并行的,所以第一个线程(通常)在被覆盖之前没有机会看到原始的 args.a
或 args.b
值.为避免这种情况,您可以为每个线程分配一个单独的 args
结构,而不是:
myarg_t * args = (myarg_t *) malloc(sizeof(myarg_t));
args->a = strlen(argv[i]);
args->b = (char *)malloc(strlen(argv[i])+1); // +1 for NUL terminator byte
strcpy(args->b, argv[i]);
pthread_create(&p[i - 1], NULL, mythread, args);
我刚开始在多线程中编程并修改一些模板,我生成了这段可能很糟糕的代码:
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
typedef struct __myarg_t //argument struct?
{
int a;
char *b;
} myarg_t;
typedef struct __myret_t //return thread struct?
{
int x;
char *y;
} myret_t;
char cat[100] = ""; //used for concatenation of argv
void *mythread(void *arg)
{
myarg_t *m = (myarg_t *)arg;
int print_index = 0;
printf("THREAD ID: %lu\n", pthread_self());
for (print_index = 0; print_index < m->a; print_index++)
{
printf("Printing %d th character %c\n", print_index, *(m->b + print_index));//spelling the words
}
myret_t *rfin = malloc(sizeof(myret_t));
rfin->x = 1;
strcat(cat, m->b);//concatenating argv with
strcat(cat, " "); //a space to cat
rfin->y = cat;//reassigning the new sentence to rfin
return (void *)rfin;
}
int main(int argc, char *argv[])
{
if (argc == 1)
{
printf("Enter a word as argument before commandline.\nExiting...\n");
exit(0);
}
int rc = 0;
pthread_t p[argc - 1]; //total threads
myret_t *m; //return thread
myarg_t args; //argument thread?
int i = 1;
while (i < argc) //creating threads:
{
printf("THREAD:\t%d\n", i);
args.a = strlen(argv[i]);
args.b = (char *)malloc(strlen(argv[i]));
strcpy(args.b, argv[i]);
pthread_create(&p[i - 1], NULL, mythread, &args);
i++;
}
i = 1;
while (i < argc) // Wait for threads to complete
{
pthread_join(p[i - 1], (void **)&m);
i++;
}
printf("returned %d %s\n", m->x, m->y); //end concatenation result for myret_t *m;
return 0;
}
所以当我执行它时:
gcc -g task2.c -o thread -Wall -pthread
./thread hello there
结果如下:
THREAD: 1
THREAD: 2
THREAD ID: 139848453601024
Printing 0 th character t
Printing 1 th character h
Printing 2 th character e
Printing 3 th character r
Printing 4 th character e
THREAD ID: 139848445208320
Printing 0 th character t
Printing 1 th character h
Printing 2 th character e
Printing 3 th character r
Printing 4 th character e
returned 1 there there
而不是 hello there
。我连接的方式有问题吗?我应该使用另一个线程来做吗?
我是否应该锁定代码的串联部分,因为不同的线程正在同时使用它?
知道我哪里出错了吗?任何 help/advice/criticism 都非常受欢迎。
您的代码中存在竞争条件——您将指向 args
的指针传递给第一个线程,然后 main()
函数立即覆盖对象中的成员变量指针指向,而第一个线程是 运行 并行的,所以第一个线程(通常)在被覆盖之前没有机会看到原始的 args.a
或 args.b
值.为避免这种情况,您可以为每个线程分配一个单独的 args
结构,而不是:
myarg_t * args = (myarg_t *) malloc(sizeof(myarg_t));
args->a = strlen(argv[i]);
args->b = (char *)malloc(strlen(argv[i])+1); // +1 for NUL terminator byte
strcpy(args->b, argv[i]);
pthread_create(&p[i - 1], NULL, mythread, args);