首页 > 解决方案 > C 线程中 pthread_create 函数的第四个参数的范围

问题描述

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

// Let us create a global variable to change it in threads
int g = 0;

// The function to be executed by all threads
void *myThreadFun(void *vargp)
{
  // Store the value argument passed to this thread
  int *myid = (int *)vargp;

  // Let us create a static variable to observe its changes
  static int s = 0;

  // Change static and global variables
  ++s; ++g;

  // Print the argument, static and global variables
  printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g);
}

int main()
{
    int i;
    pthread_t tid;

    // Let us create three threads
    for (i = 0; i < 3; i++)
        pthread_create(&tid, NULL, myThreadFun, (void *)&i);

    pthread_exit(NULL);
    return 0;
}

我只是在 C 中的多线程中使用上述示例,并且我为 2 个线程获得了相同的线程 id,这不应该是因为它myid是一个本地指针,并且每个线程都应该打印不同的。

我得到的输出如下:

Thread ID: 3, Static: 2, Global: 2
Thread ID: 3, Static: 4, Global: 4
Thread ID: 3, Static: 6, Global: 6

有人可以简要解释一下吗?

标签: cmultithreadingpthreads

解决方案


您将相同的指针传递给所有三个线程。所有线程将取消引用相同的指针,获得相同的值。

而且因为您调用pthread_exit,指针指向的数据将不再存在。这意味着取消引用将导致未定义的行为

此外,由于您在没有同步的情况下访问和修改共享数据,您的数据竞争再次导致未定义的行为

前两个问题可以通过传递i不是指向它的指针来轻松解决。这是大多数人认为可以假装整数是指针的极少数情况之一。你必须做一些铸造才能使它工作:

pthread_create(&tid, NULL, myThreadFun, (void *) (intptr_t) i);

然后在获取值时必须进行相反的转换:

int myid = (int) (intptr_t) vargp;

推荐阅读