pthread_create() 不正确的启动例程参数传递

Posted

技术标签:

【中文标题】pthread_create() 不正确的启动例程参数传递【英文标题】:Pthread_create() incorrect start routine parameter passing 【发布时间】:2016-05-05 14:10:04 【问题描述】:

我的 C++ 应用程序中的 pthread 有问题。

在我的主要功能中,我有:

int main()
    ...

    for(i=0; i<numberOfThreads; i++)
        arg[0]=i;
        pthread_create(&tidVec[i], NULL, &thread_body, (void*) arg);
        cout << "tidVec[" << i <<"]: " << tidVec[i] << " arg[0]: " << arg[0] << endl;
    

    ...

在我的 thread_body 函数中:

void * thread_body(void* arg)
    ...
    int* a = (int*)arg;
    cout << "tid: " << pthread_self() << " no.thread: " << a[0] << endl;

    ...

对此的输出(例如 numberOfThreads=2)似乎是:

tidVec[0]: 2932403008 arg[0]: 0

tidVec[1]: 2924010304 arg[0]: 1

tid: 2924010304 no.thread: 1

tid: 2932403008 no.thread: 1

在更一般的情况下,对于所有线程,numberOfThreads=n,no.thread 等于 n-1。 你能帮我弄清楚为什么吗?您如何使用启动例程有什么我不明白的地方吗?

感谢您的宝贵时间。

【问题讨论】:

请考虑使用 C++11 和 std::thread 而不是 pthreads。 【参考方案1】:

您的代码中有一个data race,因为您将同一位置的地址 (arg[0]) 传递给此处的所有线程:

    arg[0]=i;
    pthread_create(&tidVec[i], NULL, &thread_body, (void*) arg);

您可能打算使用:

   arg[i]=i;

相反。这同样适用于您在循环中执行的打印。

【讨论】:

arg 是一个长度为 2 的 int*,我用它来存储线程中所需的信息。我想要的是 arg[0] 包含线程的“数字”,而 arg[1] 是所有线程的固定值,例如10. 所以在每次迭代中,我只修改 arg 的第一个元素,然后将数组传递给 pthread_create()。有错吗? @user2440822 是的,这是错误的,因为这会导致数据竞争。您不知道按什么顺序安排线程。因此,例如,您可以将 arg[0] 设置为 1,但 thread1 可以读取它之前,主函数可以将其更改为 2。 哦,好的,现在我知道错误在哪里,我将尝试使用全局变量作为所有线程共有的值,并将 i 作为参数传递给启动例程。我的错误是我认为例程在 pthread_create 之后和修改 arg[0] 之前立即开始。非常感谢!

以上是关于pthread_create() 不正确的启动例程参数传递的主要内容,如果未能解决你的问题,请参考以下文章

正确使用pthread_create,防止内存泄漏

pthread_create中Resource temporarily unavailable问题

Android 逆向Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )

pthread_create() 和内存泄漏

pthread_create 中的错误参数

绕道的 pthread_create 产生的线程不执行指令