简体   繁体   English

为什么相同的 argv[] 在两个线程中打印两次?

[英]Why is the same argv[] printed twice in the two threads?

I just started programming in multiple threading and tinkering with some templates around, I produced this possibly horrible code:我刚开始使用多线程编程并修改了一些模板,我生成了这个可能很糟糕的代码:

#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;
}

so when I execute it:所以当我执行它时:

gcc -g task2.c -o thread -Wall -pthread
./thread hello there

It gives me the following as the result:它给了我以下结果:

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 

Instead of hello there .而不是hello there Is there some problem with the way I am concatenating?我连接的方式有问题吗? Should I be using another thread to do it?我应该使用另一个线程来做吗?

Should I lock the concatenation part of the code because different threads are using it at the same time?我应该锁定代码的连接部分,因为不同的线程同时使用它吗?

Any idea as to where I am going wrong?关于我要去哪里错的任何想法? Any help/advice/criticism is more than welcome.任何帮助/建议/批评都非常受欢迎。

You have a race condition in your code -- you pass a pointer to args to the first thread, and then the main() function immediately overwrites the member-variables in the object that the pointer points to, while the first thread is running in parallel, so the first thread (usually) doesn't get a chance to see the original args.a or args.b values before they got overwritten.您的代码中有一个竞争条件 - 您将指向args的指针传递给第一个线程,然后main() function 立即覆盖指针指向的 object 中的成员变量,而第一个线程正在运行并行,因此第一个线程(通常)在被覆盖之前没有机会看到原始的args.aargs.b值。 To avoid this, you could allocate a separate args struct for each thread, instead:为避免这种情况,您可以为每个线程分配一个单独的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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM