将值从while循环传递到线程

时间:2016-05-17 03:44:36

标签: c multithreading pointers

我有一个while循环,它获取一个值并使用该信息调用新线程中的函数。问题是我无法让它在while循环的每次迭代中为我提供一个新地址。因此while循环最终会修改正在运行的线程使用的信息。

以下是我的代码的摘录。 printf语句显示字符串的地址相同,因此在线程运行时被覆盖

    char * string = (char *) malloc(1024 * sizeof(char));
    strcpy(string, item);
    if (pthread_create(&thread, NULL, printWithDelay, &string)) {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    printf("Dispatched thread for %s at %p\n", string, &string);
    free(string);

我也尝试过没有malloc,但也没有用。有没有办法做到这一点?

在你问之前,是的我是学生,是的,这是一项任务。但是,这项任务并未要求我做任何此事。我们甚至不应该知道线程存在。我只是想让自己超越任务的范围并且遇到一些麻烦。我正在尝试将睡眠作为对我个人认识的平地机的笑话。

此处的完整代码和作业说明:http://hastebin.com/cetepakevu.c

2 个答案:

答案 0 :(得分:4)

根据您当前的pthread_create来电,您有一个竞争条件,因为您正在传递&string而不是string(即您将指针传递给主要人员)线程的string变量而不是内容)。因此,两个[或更多]子线程可能最终使用相同的字符串缓冲区。

此外,您有主线程在字符串上执行free。这必须在子线程中完成。 free全局适用于所有线程,因此在孩子可以使用数据之前free为主[或者在此后不久将其从其自身下拉出来]。

此外,"未成年人"问题的结果是:因为main执行mallocfree [假设没有子线程执行任何malloc],所以很可能是malloc将始终返回相同的值。因此,所有子线程可能使用相同的字符串缓冲区,竞争条件与否。

另一方面,如果一个子线程为其他东西做了malloc,它现在正在反对使用string [已经分配但已释放]和新分配。因此,持有/使用string的先前值的人可能会导致堆损坏[和/或段错误]如果两个区域中的任何一个被写入"右"因为malloc/heap链接指针可能位于重叠的不同分配的中间。

这是我认为你所拥有的[因为你没有展示儿童功能]:

void
main_thread(void)
{

    while (1) {
        char *string = (char *) malloc(1024 * sizeof(char));

        strcpy(string, item);

        // BUG: race condition -- on the second loop, string can be changed
        // before thread 1 has a chance to dereference it, so thread 1
        // could end up using thread 2's string (or thread 3's ...)
        if (pthread_create(&thread, NULL, printWithDelay, &string)) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }

        // BUG: child must do the free
        printf("Dispatched thread for %s at %p\n", string, &string);
        free(string);
    }
}

void *
printWithDelay(void *arg)
{
    char **strptr = arg;
    char *string;

    // BUG: this is the race condition -- we can get our string or
    // if we're delayed, we'll get the string for the next thread, so
    // we'd both use the same address
    string = *strptr;

    // use string ...

    return (void *) 0;
}

以下是更正后的代码:

void
main_thread(void)
{

    while (1) {
        char *string = (char *) malloc(1024 * sizeof(char));

        strcpy(string, item);

        if (pthread_create(&thread, NULL, printWithDelay, string)) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
    }
}

void *
printWithDelay(void *arg)
{
    char *string = arg;

    // use string ...

    free(string);

    return (void *) 0;
}

答案 1 :(得分:0)

虽然pthread_create()void *提供arg,但您可以通过投放来传递值。我还没有对此进行验证,但这个答案似乎可以做你想要的。 pthread_create: Passing argument by value

我认为最好的方法是考虑使用不同的线程api(或语言),或者只是编写一个克隆函数并传递克隆变量的地址。