c - 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
有人可以简要解释一下吗?
解决方案
您将相同的指针传递给所有三个线程。所有线程将取消引用相同的指针,获得相同的值。
而且因为您调用pthread_exit
,指针指向的数据将不再存在。这意味着取消引用将导致未定义的行为。
此外,由于您在没有同步的情况下访问和修改共享数据,您的数据竞争再次导致未定义的行为。
前两个问题可以通过传递值而i
不是指向它的指针来轻松解决。这是大多数人认为可以假装整数是指针的极少数情况之一。你必须做一些铸造才能使它工作:
pthread_create(&tid, NULL, myThreadFun, (void *) (intptr_t) i);
然后在获取值时必须进行相反的转换:
int myid = (int) (intptr_t) vargp;
推荐阅读
- java - 从登录认证中排除一个 jsf 页面
- symfony - 未知功能“资产” - Symfony 3
- c# - 在 dbcontext 中的请求之间存储数据
- git - Visual Studio 代码:自动提交 git
- java - IText7> 如何将 PdfCanvas 的内容添加为 PdfName.Figure 以实现 PDF/UA 可访问性
- php - 网站在线时无法对我的数据库执行操作
- sql - 如何只选择一列并更新它?
- javascript - 使用事务而不是firebase中的集合是否有成本开销?
- html - HTML5 视频适用于除 iPhone 以外的所有设备
- php - 为什么我的单选按钮在桌面模式下不可点击?