pthreads - pthread_t 什么时候为 0?
问题描述
我在 RHEL 7.2 中使用 pthread_create() 创建了线程。pthread_create 返回 0,但 *thread(第一个参数)为 0。
你知道线程id为0的原因吗?
pthread_t thread[6];
int nArg;
int nThread = pthread_create(&thread[0], NULL, funcA, &nArg);
if(0 > nThread)
printf("failed");
else
printf("thread started: %ld", thread[0]);
输出:线程启动:0
解决方案
我在 RHEL 7.2 中使用 pthread_create() 创建了线程。pthread_create 返回 0,但 *thread(第一个参数)为 0。
你知道线程id为0的原因吗?
暂时假设它真的是0,那又如何呢?这假定这pthread_t
是一个算术类型,当前版本的 POSIX 没有指定,但如果是这样,那么 0 是它的有效值。对于特定的线程标识符值没有记录的意义,特别是,如果线程的标识符是 type 的有效值,则没有理由认为不应将其分配为 0 作为其标识符pthread_t
。
既然您还提到了 的返回值pthread_create
,我想您可能会认为它与线程 ID 之间存在某种关系。没有记录这样的关系,除了线程 ID 的pthread_create()
值是在返回值恰好为 0 时在返回之后定义的。
但这确实指出了您的代码中的一个问题,@ErikAlapää 首先指出:pthread_create()
在失败时直接返回错误号的函数组中,而不是在失败时返回 -1 并希望您咨询errno
错误的组数字。错误编号是正数,因此if(0 > nThread)
不能依赖您的条件来检测是否pthread_create
失败。您应该针对 0 进行测试:
if (0 != nThread) {
printf("failed");
} else {
printf("thread started: %lu", (unsigned long) thread[0]);
}
printf()
还要注意第二次调用中的格式更改和强制转换。您需要第二个参数具有与格式化指令(以前是%ld
,但现在%lu
)完全对应的类型,那就是unsigned long int
. 只要pthread_t
是算术或指针类型,强制转换就有效,实际上,如果代码是其他任何东西——比如结构类型,则可以依赖编译器来拒绝代码。鉴于强制转换对于获得已知类型是必要的(但可能还不够),无符号type 更安全,因为转换定义了在原始值超出目标类型范围的情况下的行为。如果您有类型不匹配,就像您在原始代码中可能遇到的那样,那么行为是未定义的,并且在这种 UB 的无数可能表现中,最有可能的是打印“0”,尽管thread[0]
它是非零的。
尽管如此,我不会重现您的问题,即使您使用有缺陷的原始代码也是如此。我倾向于怀疑你的pthread_create
调用失败了,可能是因为你使用了一个没有线程支持的 C 库,或者链接了虚拟 pthreads 例程而不是函数式例程。确保在构建时为 pthreads 程序提供正确的选项。例如,如果您正在编译,gcc
那么您将希望提供该-pthread
选项。如果您有单独的编译和链接步骤,请同时使用该选项。
推荐阅读
- javascript - 如何从反应组件的所有详细信息标签中添加或删除“打开”属性?
- python - 对异步端点的调用被另一个线程阻塞
- cordova - 是否可以用 Cordova 包装 ASP.Net Core 网页?
- java - 为什么在数据快照中同时执行 if 和 else 语句?
- python - Keras - 如何将图像数组传递给 ImageDataGenerator.flow
- javascript - 如何使用锚标签通过链接打开我安装的应用程序,如下图所示
- kotlin - 如何使用 KTOR 库配置 ssl?
- android - 更改背景颜色后 AppCompatButton 变平
- flutter - 如何使用字符串中的名称显示包中的图标?
- bitmap - MFC 功能区 - 如何更改默认的小位图大小?