从这个例子开始:
https://computing.llnl.gov/tutorials/pthreads/samples/hello.c
我已经倒退了,并尝试编辑我希望完成的事情。 我想将数据传递给正在生成的线程。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long NUM_THREADS=0;
void *Entropy(void *depth)
{
long tid;
tid = (long)depth;
printf("This is where things get done.\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
printf("Cores: %i\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int rc;
long t;
int depth;
depth = atoi(argv[1]);
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
我在网上看到了:
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
我的函数Entropy在这里被调用,所以我想我会尝试使用某些括号并将变量传递给该函数,就像我之前看到的那样。这似乎有点不同,因为整行都返回了rc,我想知道这是否会改变我将数据传递给我的线程的方式,但我不确定我是怎么做的。< / p>
现在这段代码编译并运行,int main()顺利进行,但是当它尝试创建新线程时它会出错。
答案 0 :(得分:2)
为了将数据传递给线程,您需要在内存中的某个位置准备数据,并将指向该位置的指针传递到pthread_create
。将该指针传递给线程的转轮函数是pthread_create
的工作:
typedef struct {
long tid;
int depth;
}thread_data;
...
void *Entropy(void *dataPtr) {
thread_data *data= (thread_data*)dataPtr;
printf("This is where things get done for %li.\n", data->tid);
pthread_exit(NULL);
}
...
pthread_t threads[NUM_THREADS];
thread_data data[NUM_THREADS];
...
for(t=0;t<NUM_THREADS;t++) {
data[t].tid = t;
data[t].depth = depth;
rc = pthread_create(&threads[t], NULL, Entropy, (void *)&data[t]);
}
答案 1 :(得分:1)
您传递的错误参数导致代码崩溃:
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
// ^^^^^^^^^^^^^^
在这里你应该传递函数指针void *(*)(void *)
,但是你传递的是void *
,而且由于Entropy()
没有返回语句(你根本没有打开警告吗?),因此未指定值。我想它应该是这样的:
rc = pthread_create(&threads[t], NULL, Entropy, (void *)t);
接下来,如何将参数传递给线程例程?从技术上讲,你可以使用任何指针,但你应该三思而后行。首先,当新线程运行时,指向的数据必须有效。即你不应该传递任何本地的地址,除非你确定在离开传递数据的范围时完成了线程 - 在范围结束时使用pthread_join(new_thread)
来实现这一点。另一种方法是将指针传递给全局范围内的数据,这在任何时候都是肯定有效的。但是有一个缺陷 - 所有线程都可以看到这样的数据,因此您可能会意外地弄乱。为了避免它 - 使用动态内存 - 使用malloc()
传递指针将数据块分配给线程并在该线程中释放它。后期选项减少了破坏某人其他人数据的机会。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long NUM_THREADS=0;
void *Entropy(void *depth)
{
long tid = *((long *)depth);
free(depth);
printf("This is where things get done.\n", tid);
return NULL;
}
int main(int argc, char *argv[])
{
NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
printf("Cores: %i\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int rc;
long t;
int depth;
depth = atoi(argv[1]);
for(t=0;t<NUM_THREADS;t++){
long *arg = malloc(sizeof(*arg));
*arg = t;
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, Entropy, arg);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for(t=0;t<NUM_THREADS;t++){
pthread_join(threads[t], NULL);
}
}