如何将一个或多个变量传递给新创建的线程?

时间:2022-07-13 15:10:25

I'm learning about threads now. I'm wondering if it is possible to pass a variable to my thread. My assignement is to create a thread and assign a number (a name if you will) to each thread and print the number every 100ms. my current program is as below :

我现在正在学习线程。我想知道是否有可能将变量传递给我的线程。我的任务是创建一个线程,并为每个线程分配一个数字(如果您愿意,可以是一个名称),并每100ms打印一个数字。我目前的项目如下:

#define PCHECK(sts,msg) if((sts)!=0){printf("error : %s\n",msg); exit(EXIT_FAILURE)}
#define NB_THREAD 5

void* do_nothing(void* data)
{
    int i;

    //printf("creation thread %d",(int)data);
    while(1)
    {
        usleep(100000);
    printf("thread number : %d \n",data);
    }
    i = 0;
    pthread_exit(NULL);   
    //exit(EXIT_SUCCESS);
}

int main(int argc, char *argv[])
{
    int pid, j, status;
    pthread_t thread;
    int * res;
    int stat;

    for (j = 0; j < NB_THREAD; j++)
    {
        stat = pthread_create(&thread, NULL, do_nothing, (void *) j );
        if (stat !=0)
        {
            perror ("pthread_create()");
        }
    }
    for (j = 0; j < NB_THREAD; j++)
    {
        pthread_join(thread, (void **) &res );
    }



    return EXIT_SUCCESS;
}

for the moment the only number getting printed is 0 (the value of data). Can someone point out where did i went wrong thanks :)

目前唯一打印出来的数字是0(数据的值)。有人能指出我哪里出错了吗谢谢

2 个解决方案

#1


2  

Here are some good examples of how to pass arguments to pthreads

下面是一些如何将参数传递给pthreads的好例子

[1] https://computing.llnl.gov/tutorials/pthreads/#PassingArguments

[1]https://computing.llnl.gov/tutorials/pthreads/ PassingArguments

#2


1  

I suspect that your problem might be that your running this on a 64-bit system that uses 32-bit int types. So data is a 64-bit void* type but in your thread function you're printing it out as a 32-bit int:

我怀疑您的问题可能是在使用32位int类型的64位系统上运行这个。所以数据是一个64位的void*类型但是在线程函数中你把它作为一个32位的int类型打印出来:

// example assumes that this thread instance was started by
//   pthread_create(&thread, NULL, do_nothing, (void *) j ) when
//   j == 1

printf("thread number : %d \n",data);
                         ^       ^
                         |       +--------  passing a 64-bit pointer 0x00000000.00000001
                         |
                         +----------------  treats the pointer argument as a 32-bit int and
                                            happens to only see the all-zero 32-bits

I suspect that you'll get the output you expect if you change the printf() to:

我怀疑如果将printf()更改为:

printf("thread number : %d \n", (int) data);

As a general rule, when writing thread functions I think it's a good idea to have the first actions of the thread function be to convert the data item passed to the thread function to the type that was actually passed to pthread_create():

一般来说,在编写线程函数时,我认为最好先将传递给线程函数的数据项转换为实际传递给pthread_create()的类型:

void* do_nothing(void* data)
{
    int id = (int) data; // `pthread_create()` was passed an `int`
                         //    `data` is not used again after this point

    // ...
}

A few other points

其他几个点

  • if you pass an actual pointer to data to the thread function, make sure that each thread gets their own separate copy (unless the data is supposed to be the same instance for each thread, which is possible but uncommon).

    如果您将一个指向数据的实际指针传递给thread函数,请确保每个线程都有自己的独立副本(除非每个线程的数据应该是相同的实例,这是可能的,但并不常见)。

  • if you're spinning up multiple threads you either need to keep each pthread_t object returned by pthread_create() (in an array, maybe) so you can join on them later, or you need to call pthread_join()/pthread_detach() before reusing the pthread_t object so that the system can clean up any resources it has allocated for that thread when the thread finished running. In the example as posted that might not matter much because the threads will run forever (or until something kills the process). The pthread_join() call you have will never complete successfully.

    如果你旋转多个线程你要么需要保持每个pthread_t pthread_create()返回的对象(数组中,也许)所以你可以加入他们之后,或者你需要调用pthread_join()/ pthread_detach()之前重用pthread_t对象,这样的系统可以清除任何资源分配给线程在线程完成运行。在发布的示例中,这可能并不重要,因为线程将永远运行(或者直到某个进程终止进程)。您的pthread_join()调用永远不会成功完成。

    But the following code is destined to break when you change things so the thread function stops after some amount of time:

    但是当你改变一些事情时,下面的代码注定会被破坏,所以线程函数在一段时间后会停止:

    for (j = 0; j < NB_THREAD; j++)
    {
        pthread_join(thread, (void **) &res );
    }
    

    Because thread only has the pthread_t for the last thread created, once it successfully joins it's not valid to use any more. The next loop iteration will try to join a thread that's already been joined and is no longer valid.

    因为线程只有为创建的最后一个线程创建的pthread_t,一旦它成功加入,就不能再使用了。下一个循环迭代将尝试加入一个已经加入并且不再有效的线程。

#1


2  

Here are some good examples of how to pass arguments to pthreads

下面是一些如何将参数传递给pthreads的好例子

[1] https://computing.llnl.gov/tutorials/pthreads/#PassingArguments

[1]https://computing.llnl.gov/tutorials/pthreads/ PassingArguments

#2


1  

I suspect that your problem might be that your running this on a 64-bit system that uses 32-bit int types. So data is a 64-bit void* type but in your thread function you're printing it out as a 32-bit int:

我怀疑您的问题可能是在使用32位int类型的64位系统上运行这个。所以数据是一个64位的void*类型但是在线程函数中你把它作为一个32位的int类型打印出来:

// example assumes that this thread instance was started by
//   pthread_create(&thread, NULL, do_nothing, (void *) j ) when
//   j == 1

printf("thread number : %d \n",data);
                         ^       ^
                         |       +--------  passing a 64-bit pointer 0x00000000.00000001
                         |
                         +----------------  treats the pointer argument as a 32-bit int and
                                            happens to only see the all-zero 32-bits

I suspect that you'll get the output you expect if you change the printf() to:

我怀疑如果将printf()更改为:

printf("thread number : %d \n", (int) data);

As a general rule, when writing thread functions I think it's a good idea to have the first actions of the thread function be to convert the data item passed to the thread function to the type that was actually passed to pthread_create():

一般来说,在编写线程函数时,我认为最好先将传递给线程函数的数据项转换为实际传递给pthread_create()的类型:

void* do_nothing(void* data)
{
    int id = (int) data; // `pthread_create()` was passed an `int`
                         //    `data` is not used again after this point

    // ...
}

A few other points

其他几个点

  • if you pass an actual pointer to data to the thread function, make sure that each thread gets their own separate copy (unless the data is supposed to be the same instance for each thread, which is possible but uncommon).

    如果您将一个指向数据的实际指针传递给thread函数,请确保每个线程都有自己的独立副本(除非每个线程的数据应该是相同的实例,这是可能的,但并不常见)。

  • if you're spinning up multiple threads you either need to keep each pthread_t object returned by pthread_create() (in an array, maybe) so you can join on them later, or you need to call pthread_join()/pthread_detach() before reusing the pthread_t object so that the system can clean up any resources it has allocated for that thread when the thread finished running. In the example as posted that might not matter much because the threads will run forever (or until something kills the process). The pthread_join() call you have will never complete successfully.

    如果你旋转多个线程你要么需要保持每个pthread_t pthread_create()返回的对象(数组中,也许)所以你可以加入他们之后,或者你需要调用pthread_join()/ pthread_detach()之前重用pthread_t对象,这样的系统可以清除任何资源分配给线程在线程完成运行。在发布的示例中,这可能并不重要,因为线程将永远运行(或者直到某个进程终止进程)。您的pthread_join()调用永远不会成功完成。

    But the following code is destined to break when you change things so the thread function stops after some amount of time:

    但是当你改变一些事情时,下面的代码注定会被破坏,所以线程函数在一段时间后会停止:

    for (j = 0; j < NB_THREAD; j++)
    {
        pthread_join(thread, (void **) &res );
    }
    

    Because thread only has the pthread_t for the last thread created, once it successfully joins it's not valid to use any more. The next loop iteration will try to join a thread that's already been joined and is no longer valid.

    因为线程只有为创建的最后一个线程创建的pthread_t,一旦它成功加入,就不能再使用了。下一个循环迭代将尝试加入一个已经加入并且不再有效的线程。