4

这是我的代码。这很简单。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *func(void *arg)
{
    printf("ID=%d\n", *(int*)arg);
    pthread_exit(NULL);
}

int main()
{
    pthread_t pt[4];
    int i;

    for (i = 0; i < 4; i++)
    {
        int temp = i;
        pthread_create(&pt[i], NULL, func, (void*)&temp);
    }
    sleep(1);
    return 0;
}

我编译它:

gcc p_test.c -lpthread

我跑了。它打印了2 2 3 3。我又跑了一遍。它打印了2 3 3 2

我的问题是:

为什么要打印两次23

为什么它没有打印1 3 2 0或任何其他结果?

4

4 回答 4

7

这里的主要问题是您正在获取局部变量的地址temp,然后在变量范围之外使用该指针 - 一旦您退出循环的一次迭代,您的指针temp就会变得无效并且您不能取消引用它。

于 2012-06-04T12:19:17.673 回答
3

您将指向临时变量的指针传递给线程创建函数,并且该临时变量在循环块的末尾超出范围。在我看来,编译器正在重用临时地址,因此当线程执行时,它们会看到相同的地址位置。

如果你这样做:

int *temp = malloc(sizeof(int));
*temp = i;
pthread_create(&pt[i], NULL, func, (void*)temp);

相反,您应该会看到预期的结果。

在这种情况下,线程函数需要在int打印后释放它以避免内存泄漏。

此外,最好对pthread_join()您正在等待的线程进行练习,而不仅仅是sleep()ing。

于 2012-06-04T12:21:15.060 回答
0
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *func(void* arg)
{
printf("ID=%d\n", (int)arg);
pthread_exit(NULL);
return 0;
}

int main()
{
pthread_t pt[4];
int i;

for (i =0 ; i < 4; i++)
{

    pthread_create(&pt[i], NULL, func, (void*)i);
    pthread_join(pt[i],NULL);
}



return 0;

}

于 2014-12-02T09:56:51.323 回答
0

因为它打印 temp,所以所有线程共享内存(TheJuice 解释了为什么 temp 是“共享”的),所以所有线程都“共享” temp 。使用互斥锁或将 temp 设为私有变量。 线程中的私有变量

或者你可以像这样使用phtread_join

int main()
{
    pthread_t pt[4];
    int i;

    for (i =0 ; i < 4; i++)
    {

      pthread_create(&pt[i], NULL, func, (void*)&i);
      pthread_join(pt[i],NULL);

    }

    //sleep(1);
    return 0;
}
于 2012-06-04T12:28:04.083 回答