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

问题描述 投票:0回答:6

我有以下功能:

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
的最后一个参数?

c pthreads
6个回答
55
投票

基于 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
的地址那样遇到任何线程安全问题。在这种情况下,您还可以设置一个数组并传递元素的地址。


27
投票

您可以在堆上分配一个

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);
}

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[])
或其等效项。


8
投票

老问题,但我今天遇到了同样的问题,我决定不走这条路。 我的应用程序确实与性能有关,因此我选择静态声明这个

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
投票

虽然这是一个老问题,但当您需要传递一个正整数(如描述符)时,缺少一个选项:您可以直接将其作为地址传递,虽然它是一种 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;
}

0
投票

你可以

intprt_t

当您需要在指针和整数之间进行转换而不丢失信息时,或者当您希望确保指针可以安全地转换为整数类型时,使用 intptr_t 非常有用。它通常用于需要将指针存储在整数变量中或将指针作为整数参数传递给函数的场景。

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

int main() {
    pthread_t thread;
    int i;
    pthread_create(&thread, 0, foo, (void *)(intptr_t)i);  // cast i to intptr_t type
}
© www.soinside.com 2019 - 2024. All rights reserved.