我有以下功能:
void *foo(void *i) {
int a = (int) i;
}
int main() {
pthread_t thread;
int i;
pthread_create(&thread, 0, foo, (void *) i);
}
在编译时,有一些关于强制转换的错误((void *) i
和int a = (int) i
)。如何正确传递整数作为pthread_create
的最后一个参数?
答案 0 :(得分:35)
以szx的答案为基础(所以给予他信任),以下是它在for
循环中的工作原理:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
for ( int i = 0; i < 10; ++1 ) {
int *arg = malloc(sizeof(*arg));
if ( arg == NULL ) {
fprintf(stderr, "Couldn't allocate memory for thread arg.\n");
exit(EXIT_FAILURE);
}
*arg = i;
pthread_create(&thread, 0, foo, arg);
}
/* Wait for threads, etc */
return 0;
}
在循环的每次迭代中,你要分配新的内存,每个内存都有不同的地址,所以在每次迭代时传递给pthread_create()
的东西是不同的,所以你的线程都没有尝试访问相同的内存,如果您刚刚传递i
的地址,就不会遇到任何线程安全问题。在这种情况下,您还可以设置一个数组并传递元素的地址。
答案 1 :(得分:21)
您可以在堆上分配int
并将其传递给pthread_create()
。然后,您可以在线程函数中释放它:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
int *i = malloc(sizeof(*i));
pthread_create(&thread, 0, foo, (void *) i);
}
答案 2 :(得分:10)
您应该在pthread_create()的最后一个参数中转换i
的地址(而不是现在的i
的值)。
pthread_create(&thread, 0, foo, (void *) &i);
^ is missing
你的功能也是错误的。它应该是:
int a = *((int*) i);
i
初始化为main()中的某个值,因为它现在未初始化。2对main()使用正确的定义:
int main(void)
或int main(int argc, char *argv[])
或其等价物。
答案 3 :(得分:6)
老问题,但我今天遇到了同样的问题,我决定不遵循这条道路。
我的应用程序实际上是关于性能的,所以我选择静态声明这个int
数组。
由于我不知道很多应用程序中pthread_join
/ pthread_cancel
位于另一个范围而不是pthread_create
,我选择了这种方式:
#define NB_THREADS 4
void *job(void *_i) {
unsigned int i = *((unsigned int *) _i);
}
int main () {
unsigned int ints[NB_THREADS];
pthread_t threads[NB_THREADS];
for (unsigned int i = 0; i < NB_THREADS; ++i) {
ints[i] = i;
pthread_create(&threads[i], NULL, job, &ints[i]);
}
}
我发现它更优雅,更高效,而且您不必担心自由,因为它只存在于此范围内。
答案 4 :(得分:0)
虽然这是一个老问题但是当你需要的是传递像描述符这样的正整数时,有一个选项缺失:你可以直接传递它作为地址,而它是一个hack它运行良好并避免分配任何东西: )
注意:整数的大小必须与操作系统上指针的大小相匹配,但现在大多数系统都是本机64位。
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
void *_thread_loop(void *p)
{
uint64_t n = (uint64_t)p;
printf("received %llu\n", n);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t read_thread_id;
uint64_t n = 42;
pthread_create(&read_thread_id, NULL, _thread_loop, (void *)n);
pthread_join(read_thread_id, NULL);
return 0;
}