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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19232957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:39:29  来源:igfitidea点击:

pthread_create and passing an integer as the last argument

cpthreads

提问by Gradient

I have the following functions :

我有以下功能:

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

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

At compilation, there are some errors about casting ((void *) iand int a = (int) i). How can I pass an integer as the last argument of pthread_createproperly?

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

回答by Crowman

Building on szx's answer (so give him the credit), here's how it would work in your forloop:

基于 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;
}

On each iteration of the loop, you're allocating new memory, each with a different address, so the thing that gets passed to pthread_create()on each iteration is different, so none of your threads ends up trying to access the same memory and you don't get any thread safety issues in the way that you would if you just passed the address of i. In this case, you could also set up an array and pass the addresses of the elements.

在循环的每次迭代中,您都在分配新内存,每个内存都有不同的地址,因此pthread_create()在每次迭代中传递的内容是不同的,因此您的线程最终都不会尝试访问相同的内存,而您没有如果您只是传递i. 在这种情况下,您还可以设置一个数组并传递元素的地址。

回答by szx

You can allocate an inton the heap and pass it to pthread_create(). You can then deallocate it in your thread function:

您可以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);
}

回答by P.P

You should cast the address of i(rather than the value of ias you do now) in the last argument of pthread_create().

您应该在 pthread_create() 的最后一个参数中强制转换(i而不是i像您现在所做的那样的值)的地址。

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

And the casting is wrong in your function too. It should be:

而且您的功能中的转换也是错误的。它应该是:

int a = *((int*) i);
  1. If you intend to readthe value, you should also initialize ito some value in main() as it's uninitialized now.
  1. 如果您打算读取该值,您还应该i在 main() 中初始化为某个值,因为它现在尚未初始化。

2 Use proper definition for main():

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

 int main(void) 

or int main(int argc, char *argv[])or its equivalent.

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

回答by Jerska

Old question, but I faced the same problem today, and I decided not to follow this path. My application was really about performance, so I chose to have this array of ints declared statically.

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

Since I don't know a lot of applications where your pthread_join/ pthread_cancelis in another scope than your pthread_create, I chose this way :

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

I find it more elegant, more efficient, and you don't have to worry about freeing since it only lives in this scope.

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

回答by Schmurfy

While this is an old question there is one option missing when all you need is to pass a positive integer like a descriptor: you can pass it directly as the address, while it it a hack it works well and avoid allocating anything :)

虽然这是一个老问题,但当您只需要传递一个像描述符一样的正整数时,就会缺少一个选项:您可以将它直接作为地址传递,虽然它是一个 hack,但它运行良好并避免分配任何内容:)

NOTE: the size of the integer must match the size of a pointer on your OS but nowadays most systems are native 64bits.

注意:整数的大小必须与操作系统上指针的大小匹配,但现在大多数系统都是本机 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;
}