#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);
}
}
}
我遇到了麻烦,创建并加入了一个帖子。我也不确定如何通过引用传递线程参数的语法。代码应该在创建线程时打印,以及在线程例程中休眠多长时间。
答案 0 :(得分:0)
您发布的代码使用pthread_create()
允许您传递给线程函数的单个参数来执行“坏事”。 pthread_create()
允许传递单个void *
(通常可以通过从其他内容中转换来获得)。在你的情况下,你这样做:
pthread_create(..., (void * ) jj)
这将获取存储在jj
中的整数值,将其重新解释为void *
,并且此指针将传递给您的线程函数。严格来说,将int
重新解释为void *
充其量是可疑的,但这就是设计PThreads API的方式。
在你的线程函数中,你这样做:
int myThreadNumber = * ((int * ) threadArg);
这将获取您传递的void *
,并将其重新解释为指向int
(又名(int *)
)的指针,这在大多数平台上通常是可以接受的,但会导致在您的使用中,int *
的值为0
或1
,...然后,您尝试取消引用此指针,以使用int
获取* ((int *) ...)
。在大多数现代系统中,循环的第一次迭代将因此导致空指针取消引用(尽管NULL指针不能保证数字值为0,但这些天通常会在大多数系统/编译器上执行),并且可能会导致结果导致程序崩溃,除非您正在捕捉并忽略相关信号等。
你应该在你的线程函数中做的是将void *
强制转换回从开始构建的。换句话说,int myThreadNumber = (int) threadArg
。或者,你可以改为调用pthread_create(.... (void *) &jj)
,如果你真的想要一个指向int
的指针,那么你可以传回信息 - 但这似乎不是你在这里想要做的,并且将指针传递给基于堆栈的局部变量在其他方面会是一件坏事。
我不确定您对通过引用与值传递参数的期望是什么。 API声明您必须传递void *
,这就是您必须做的事情,除非您想请求PThreads人员更改API ...或者自己编写...
答案 1 :(得分:0)
你在做什么:
pthread_create( & threads[jj], NULL, threadRoutine, (void * )jj) ;
将int jj
转换为void*
,并将值传递给threadRoutine()
。这很合理。问题似乎是在threadRoutine()
你:
int myThreadNumber = * ((int * ) threadArg);
这就是我们所说的&#34;一个错误&#34;。应该做的是:
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个线程使用,并且一直存在,直到该线程已加入beem之后...所以一切都很好。