3

通读 LLNL的 pthread教程,我点击了以下示例代码

/******************************************************************************
* FILE: hello.c
* DESCRIPTION:
*   A "hello world" Pthreads program.  Demonstrates thread creation and
*   termination.
* AUTHOR: Blaise Barney
* LAST REVISED: 08/09/11
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0;t<NUM_THREADS;t++){
     printf("In main: creating thread %ld\n", t);
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
     if (rc){
       printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(-1);
       }
     }

   /* Last thing that main() should do */
   pthread_exit(NULL);
}

我可以看到为什么long通过void *(好像不是,并且您传递一个指向t由线程打印的数字的指针是乱码),我的问题是这应该被认为是犹太洁食并且总是有效吗?或者这是获得最简单的线程工作示例的快速技巧?这是标准的 C 语言吗?

4

2 回答 2

4

不,就 ISO C 标准而言,这并不是严格意义上的犹太教,因为不能保证指针的宽度足以容纳长指针。

一个 kosher 解决方案是传递一个指向long 的指针,或者每个线程使用一个唯一的 long(例如数组中的一个),或者在创建者线程和创建线程之间进行线程间通信(例如条件变量),以便后者可以在前者被允许为下一个线程创建更改它之前进行复制。

然而,它不是严格意义上的 kosher 的事实并不意味着它在特定的实现中不起作用。只要您可以保证演员之间的转换void*并且long不会丢失任何信息,它可能会正常工作。

从 C11 开始6.3.2.3 Pointers(尽管它与 C99 基本没有变化):

整数可以转换为任何指针类型。除非前面指定,结果是实现定义的,可能没有正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。

任何指针类型都可以转换为整数类型。除非前面指定,结果是实现定义的。如果结果不能以整数类型表示,则行为未定义。结果不必在任何整数类型的值范围内。

于 2012-09-05T05:24:20.473 回答
0

它仅适用于 32 位系统,在 64 位系统的情况下,long 的大小为 32 位,但 void* 的大小为 64 位。

于 2012-09-05T05:29:26.393 回答