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

const int kMaxThreads = 10;

void * threadRoutine(void * threadArg) {
    int myThreadNumber = * ((int * ) threadArg);
    //(int)threadArg
    printf("threadRoutine()=>: this is thread number %d!\n", myThreadNumber);
    int sleepTime = random() % 20;
    sleep(sleepTime);
    printf("threadRoutine()=>: thread[%d] completed after sleeping %d [secs]!\n",
        myThreadNumber, sleepTime);
    pthread_exit((void * ) myThreadNumber);
}

int main(int argc, char * argv[]) {
    pthread_t threads[kMaxThreads];
    printf("main()=>: creating threads...\n");
    for (int jj = 0; jj < kMaxThreads; jj++) {
        if (pthread_create( & threads[jj], NULL, threadRoutine, (void * ) jj) != 0) {
            /* undefined reference to a pthread_create*/
        } else {
            printf("main()=>: created thread[%d]!\n", jj);
        }
    }
    printf("main()=>: waiting for threads to complete...\n");
    for (int jk = 0; jk < kMaxThreads; jk++) {
        void * currentThread;
        if (pthread_join(threads[jk], & currentThread) != 0) {
            /* undefined reference to a pthread_join*/
        } else {
            printf("main()=>: completed thread[%d]!\n", (int) currentThread);
        }
    }
}

我在创建和加入线程时遇到了麻烦。我也不确定如何通过引用传递线程参数的语法。代码应该在创建线程时打印以及它在线程例程中休眠多长时间。

4

2 回答 2

0

你在做什么:

  pthread_create( & threads[jj], NULL, threadRoutine, (void * )jj) ;

正在铸造int jjto void*,并将该传递给您的threadRoutine(). 这足够合理。问题似乎在于threadRoutine()您:

  int myThreadNumber = * ((int * ) threadArg);

这就是我们所说的“错误”。应该做的是:

  int myThreadNumber = (int)threadArg ;

或者可能:

  int myThreadNumber = (intptr_t)threadArg ;

void*指针转换回原来的值int

要通过jj引用传递需要以下内容:

  int thread_arg[kMaxThreads] ;

  for (int jj = 0; jj < kMaxThreads; jj++) {
    thread_arg[jj] = jj ;
    if (pthread_create( & threads[jj], NULL, threadRoutine, &thread_arg[jj]) != 0) {
        /* undefined reference to a pthread_create*/
    } ...

然后你原创

  int myThreadNumber = * ((int * ) threadArg);

可以拿起价值。

当然,线程有权在threadArg运行时随时使用指向的东西......所以你需要确保它在那么长时间内保持有效。在这种情况下,thread_arg[jj]它仅由第'jj'个线程使用,并且在该线程被加入之前一直存在......所以一切都很好。

于 2014-10-23T18:30:07.867 回答
0

pthread_create()您发布的代码正在使用允许您传递给线程函数的单个参数做“坏事” 。pthread_create()允许传递一个单一void *的(它可以而且通常是通过从其他东西转换而来的)。在您的情况下,您正在这样做:

pthread_create(..., (void * ) jj)

这将获取存储在 中的整数值jj,将其重新解释为 a void *,并且此指针是传递给您的线程函数的内容。严格来说,将 an 重新解释int为 avoid *充其量是可疑的,但这就是 PThreads API 的设计方式。

但是,在您的线程函数中,您正在执行以下操作:

int myThreadNumber = * ((int * ) threadArg);

这将获取void *您传递的 ,并将其重新解释为指向int(aka (int *)) 的指针,这在大多数平台上通常是可以接受的,但在您的使用中会导致 anint *的值为0, or 1, ...。然后,您尝试取消引用此指针以获取int, 与您的* ((int *) ...). 在大多数现代系统上,循环的第一次迭代将因此导致空指针取消引用(尽管不保证 NULL 指针的数值为 0,但现在大多数系统/编译器通常都会这样做),并且可能会导致结果导致程序崩溃,除非您正在捕获并忽略相关信号等。

你应该在你的线程函数中做的就是把它void *转换成它从一开始就被转换的东西。换句话说,int myThreadNumber = (int) threadArg. 或者,pthread_create(.... (void *) &jj)如果你真的想要一个指向的指针,你可以改为调用,int这样你就可以将信息传回——但这似乎不是你在这里想要做的,并将一个指针传递给一个基于堆栈的局部变量在其他方面将是一件坏事。

我不确定您对能够通过引用与值传递参数的期望。API 声明您必须通过 a void *,所以这是您必须做的,除非您想请求 PThreads 人员更改 API... 或编写您自己的...

于 2014-10-23T18:27:42.407 回答