C语言 Linux Pthread argument



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

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void *arg)
{
    printf("ID=%dn", *(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或任何其他结果?

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

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

如果您这样做:

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

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

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

此外,更好的做法是pthread_join()您正在等待的线程,而不仅仅是sleep()

因为它打印temp,所以所有线程共享内存(为什么temp是"共享"由TheJuice解释),所以所有线程"共享"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;
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void* arg)
{
printf("ID=%dn", (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;

}

最新更新