42

我有以下功能:

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

int main() {
    pthread_t thread;
    int i;
    pthread_create(&thread, 0, foo, (void *) i);
}

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

4

5 回答 5

53

建立在 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. 在这种情况下,您还可以设置一个数组并传递元素的地址。

于 2013-10-07T23:02:03.537 回答
25

您可以在堆上分配一个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);
}
于 2013-10-07T19:31:22.803 回答
11

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

pthread_create(&thread, 0, foo, (void *) &i);
                                         ^  is missing

而且你的功能也是错误的。它应该是:

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

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

 int main(void) 

int main(int argc, char *argv[])或其等价物。

于 2013-10-07T19:35:50.583 回答
8

老问题,但我今天遇到了同样的问题,我决定不走这条路。我的应用程序实际上是关于性能的,所以我选择int静态声明这个 s 数组。

由于我不知道很多您的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]);
  }
}

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

于 2014-07-29T04:50:01.007 回答
3

虽然这是一个老问题,但当您只需要传递一个像描述符这样的正整数时,缺少一个选项:您可以直接将它作为地址传递,而它是一个 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;
}
于 2018-01-16T07:30:27.883 回答