2

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

#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(数据的值)。有人可以指出我哪里出错了谢谢:)

4

2 回答 2

2

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

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

于 2012-05-19T07:25:15.390 回答
1

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

作为一般规则,在编写线程函数时,我认为让线程函数的第一个动作是将传递给线程函数的数据项转换为实际传递给的类型是个好主意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_tpthread_join()

    但是,当您更改内容时,以下代码注定会中断,因此线程函数会在一段时间后停止:

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

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

于 2012-05-19T17:19:33.133 回答