Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将值从while循环传递到线程中_C_Multithreading_Pointers - Fatal编程技术网

C 将值从while循环传递到线程中

C 将值从while循环传递到线程中,c,multithreading,pointers,C,Multithreading,Pointers,我有一个while循环,它获取一个值并使用该信息在一个新线程中调用一个函数。问题是我无法让它在while循环的每次迭代中为这些信息提供一个新地址。因此while循环最终会修改正在运行的线程所使用的信息 这是我代码的一个摘录。printf语句显示字符串的地址相同,因此在线程运行时被覆盖 char * string = (char *) malloc(1024 * sizeof(char)); strcpy(string, item); if (pthread_create(

我有一个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,但也不起作用。有没有办法做到这一点

在你问之前,是的,我是一名学生,是的,这是一项作业。然而,作业并没有要求我做这些。我们甚至不应该知道线程的存在。我只是想让自己超越任务的界限,现在有点麻烦。我试着对我认识的评分员开个玩笑


此处的完整代码和赋值说明:

尽管
pthread_create()
会使用
void*
作为
arg
,但您可以通过强制转换来传递值。我还没有证实这一点,但是这个答案似乎符合你的要求


<>我认为最好的办法是考虑一个不同的线程API(或语言)或者简单地写一个克隆函数并传递克隆变量的地址。

虽然pthRead SkEATE()>代码>采用了<代码> Value*>代码>对于它的<代码> ARG,可以通过铸造来传递值。我还没有证实这一点,但是这个答案似乎符合你的要求


<>我认为最好的办法是考虑一个不同的线程API(或语言)或者简单地写一个克隆函数并传递克隆变量的地址。

用你现在的代码> pthRead创建/<代码>调用,你有一个竞争条件,因为你正在通过<代码>字符串>代码>而不是<代码>字符串< /代码>。(即,您正在传递一个指向主线程的
字符串
变量的指针,而不是它的内容)。因此,两个[或更多]子线程可能最终使用相同的字符串缓冲区

另外,主线程在字符串上执行
free
。这必须在子线程中完成。
free
对所有线程全局工作,因此在子线程可以使用数据[或在不久之后将其从自身下方拉出]之前,main执行
free

此外,由此产生的“次要”问题是:因为
main
执行
malloc
,而
free
[假设没有子线程执行任何
malloc
],很可能
malloc
将始终返回相同的值。因此,所有子线程可能使用相同的字符串缓冲区,无论是否使用竞争条件

另一方面,如果子线程为其他对象执行
malloc
,则它现在正在与
string
[已分配但已释放]和新分配的使用竞争。因此,持有/使用
string
的先前值可能会导致堆损坏[和/或segfault]如果两个区域中的任一个以“正确”的方式写入,因为<代码> MalcC/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;
}

在当前的
pthread\u create
调用中,由于传递的是
&string
而不是
string
(即,传递的是指向主线程的
string
变量的指针,而不是其内容),因此,两个[或更多]子线程可能最终使用相同的字符串缓冲区

另外,主线程在字符串上执行
free
。这必须在子线程中完成。
free
对所有线程全局工作,因此在子线程可以使用数据[或在不久之后将其从自身下方拉出]之前,main执行
free

此外,由此产生的“次要”问题是:因为
main
执行
malloc
,而
free
[假设没有子线程执行任何
malloc
],很可能
malloc
将始终返回相同的值。因此,所有子线程可能使用相同的字符串缓冲区,无论是否使用竞争条件

另一方面,如果子线程为其他对象执行
malloc
,则它现在正在与
string
[已分配但已释放]和新分配的使用竞争。因此,持有/使用
string
的先前值可能会导致堆损坏[和/或segfault]如果两个区域中的任一个以“正确”的方式写入,因为<代码> MalcC/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;
}

快速而肮脏的解决方案是删除
free
。另一个选项是在使用内存时让线程调用
free
。最后一个选项是让
main
call
pthread\u join
等待线程完成,然后调用
free
。我已经尝试过使用和不使用free。我已经尝试过了也尝试使用char string[1024];而不是。哦,在调用
pthread_create
时,
&string
应该是
string
。您传递的是指针的地址,地址总是相同的。1)
虽然
循环是一个语句,但它不能“将值传递到线程”2)没有
while
(或任何其他)循环如图3)所示。完整代码可在原始帖子中找到。快速而肮脏的解决方案是删除
免费
。另一个选项是在内存中完成线程调用时释放线程调用。最后一个选项是让
main
call
pthread\u连接<