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

时间:2012-05-19 07:20:47

标签: c linux pthreads

我现在正在学习线程。我想知道是否可以将变量传递给我的线程。我的任务是创建一个线程并为每个线程分配一个数字(如果你愿意的话),并每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;
}

目前唯一打印的数字是0(数据的值)。有人可以指出我哪里出错了,谢谢:)

2 个答案:

答案 0 :(得分:2)

以下是如何将参数传递给pthreads

的一些很好的例子

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

答案 1 :(得分:1)

我怀疑您的问题可能是您在使用32位int类型的64位系统上运行此问题。因此data是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

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

,您将获得预期的输出
printf("thread number : %d \n", (int) data);

作为一般规则,在编写线程函数时,我认为让线程函数的第一个动作是将传递给线程函数的数据项转换为实际传递给{{1}的类型是个好主意。 }:

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 // ... } 返回的每个pthread_t对象(可能在一个数组中),这样您以后可以加入它们,或者您需要在重用pthread_create()对象之前调用pthread_join() / pthread_detach(),以便系统可以清除线程完成运行时为该线程分配的所有资源。在发布的示例中,可能并不重要,因为线程将永远运行(或直到某些东西杀死进程)。您拥有的pthread_t电话将永远无法成功完成。

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

    pthread_join()

    因为for (j = 0; j < NB_THREAD; j++) { pthread_join(thread, (void **) &res ); } 只有最后一个线程创建的thread,所以一旦成功加入它就无法再使用了。下一个循环迭代将尝试加入已经加入并且不再有效的线程。