pthread_create并传递一个整数作为最后一个参数

Gra*_*ent 34 c pthreads

我有以下功能:

void *foo(void *i) {
    int a = (int) i;
}

int main() {
    pthread_t thread;
    int i;
    pthread_create(&thread, 0, foo, (void *) i);
}
Run Code Online (Sandbox Code Playgroud)

在编译时,有一些关于强制转换((void *) iint a = (int) i)的错误.如何pthread_create正确传递整数作为最后一个参数?

Cro*_*man 40

基于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;
}
Run Code Online (Sandbox Code Playgroud)

在循环的每次迭代中,你要分配新的内存,每个内存都有不同的地址,所以pthread_create()在每次迭代时传递给它的东西是不同的,所以你的所有线程都不会试图访问相同的内存而你不会如果您刚刚传递了地址,就会遇到任何线程安全问题i.在这种情况下,您还可以设置一个数组并传递元素的地址.

  • @Gradient:您必须将其编译为C++.在C中不需要演员表,在我看来,不应该包括在内. (2认同)
  • @Pegasus:你错了.在这里,您希望为`int`分配正确的空间量,而不是指向`int`的指针.你的替代方案会做后者,所以实际上你的建议只有在指针和`int`s大小相同时才有效. (2认同)

szx*_*szx 22

您可以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);
}
Run Code Online (Sandbox Code Playgroud)


P.P*_*.P. 10

你应该在pthread_create()的最后一个参数中转换地址i(而不是i你现在的值).

pthread_create(&thread, 0, foo, (void *) &i);
                                         ^  is missing
Run Code Online (Sandbox Code Playgroud)

你的功能也是错误的.它应该是:

int a = *((int*) i);
Run Code Online (Sandbox Code Playgroud)
  1. 如果您打算读取该值,您还应该i在main()中初始化为某个值,因为它现在未初始化.

2对main()使用正确的定义:

 int main(void) 
Run Code Online (Sandbox Code Playgroud)

int main(int argc, char *argv[])或等同物.

  • 我不确定第二种解决方案是否有效.到那时,第一个线程到达`int a =*((int*)i)`,for循环可能改变了`i`的值.因此,当第一个线程尝试初始化`a`时,它不会读取正确的值. (2认同)

Jer*_*ska 7

老问题,但今天我遇到了同样的问题,我决定不遵循这条道路.我的应用程序实际上是关于性能的,所以我选择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]);
  }
}
Run Code Online (Sandbox Code Playgroud)

我发现它更优雅,更高效,而且你不必担心自由,因为它只存在于这个范围内.