它是否需要互斥锁才能将参数传递给 pthread?

Does it require mutex locking for arguments to be passed to pthread?

本文关键字:参数传递 pthread 是否      更新时间:2023-10-16

我有一个将被多次调用的函数,这个函数每次被调用都会创建一个新的pthread。我需要在每次创建时都使用结构将一些参数传递给 pthread。

每当将参数传递给 pthread 时,是否需要为这些结构(在创建 pthread 的函数中(设置互斥锁?

请指教。

我需要在每次创建时使用 struct 将一些参数传递给 pthread。

我想你一定是这样想的:

struct args {
    int arg1;
    double arg2;
    char *arg3;
};
void *thread_func(void *p) {
    struct args *args = p;
    // ... do something with args ...
    return some_value;
}
// ...
void foo() {
    pthread_t tid;
    struct args *args;
    // ...
    args = some_expression;
    pthread_create(&tid, NULL, thread_func, args);
    // ...
}

是否需要为这些结构设置互斥锁(在 创建 pthread( 的函数(每当将参数传递给 线程?

单独在功能中使用互斥锁foo()对任何人都没有好处。 互斥体仅在两个不同的代码段之间提供同步,这两个代码段都成功锁定了同一代码段(必然在不同的时间(。

更一般地说,启动新线程会将新线程中的所有操作与父线程中线程启动之前的所有操作同步。 特别是,新线程可以在没有任何特殊措施的情况下读取参数结构的内容,并且不会因此引起数据争用,前提是没有其他线程修改该结构,并且结构的生存期不会过期。 新线程甚至可以在没有数据争用的情况下修改参数结构,前提是根本没有其他线程访问它,并且它的生存期不会过期。

但是,正如上述附带条件所暗示的那样,您肯定仍然会遇到麻烦。 适当的双边或多边使用互斥锁可以解决一些此类问题,但不能解决其他问题。 例如,如果呈现给新线程的 args 结构实际上是启动线程的函数的自动变量,并且线程实际上通过提供的指针访问结构,那么新线程访问结构与其生命周期结束之间存在潜在的数据争用。 例如

void foo() {
    pthread_t tid;
    struct args args;  // an automatic variable
    // ...
    pthread_create(&tid, NULL, thread_func, &args);
    // ...
    // the lifetime of args ends when control reaches here
}

在这种情况下,您需要确保新线程在返回foo()(在不同的线程中运行(之前执行其对 args 结构的所有访问。 互斥锁(单独(不能为你做到这一点 - 相反,你需要一个条件变量(必须与互斥锁一起使用(,或者信号量,或者各种其他替代方案之一。