【问题标题】:Does using locals as arguments in pthread_create() work?在 pthread_create() 中使用局部变量作为参数有效吗?
【发布时间】:2018-02-01 05:23:52
【问题描述】:

这主要是关于范围和线程的问题。假设我们有以下结构。

struct Test
{
  int number;
  std::string name;
};

此结构的实例将用作 pthread_create 函数中的参数。这是一个可能看起来像的示例。

pthread_t tid[5];
for(int i = 0; i < 5; ++i)
{
  Test test;
  test.number = 5;
  test.name = "test";
  pthread_create(&tid[i], NULL, func, (void *)&test);
}

这可以接受吗?由于 test 是在 for 的范围内声明的,这意味着我们只能依赖它在 for 循环的单次迭代中存在。

当调用 pthread_create 时,会给出一个指向 test 的指针作为参数。这意味着 func 正在接收与传递给 pthread_create 相同的指针。这意味着当 test 超出范围时,我们不能再依赖指向 test 的指针。如果我们要创建更多的局部变量,从而更改堆栈,则指针指向的位置将被那些新的局部变量覆盖。它是否正确?

【问题讨论】:

    标签: c++ pointers pthreads


    【解决方案1】:

    这可以接受吗?

    一般来说,不,因为你所说的原因。具体来说,线程的入口函数可能直到 Test 对象被销毁后才开始执行,或者 Test 对象可能在线程的入口函数仍在使用它时被销毁。这些可能性中的任何一种都将导致未定义的行为(以及仅“有时”正常工作的程序)。

    您需要保证您传递给线程的数据在线程需要使用它时一直有效。一种方法是在堆上分配该 Test 对象,并在使用完成后让线程在 Test-pointer 上调用 delete。或者,您可以使用条件变量来“暂停”主线程,直到子 pthread 发出信号表明它已完成对主线程堆栈上的测试的访问,以便主线程现在可以安全地继续执行。

    如果我们要创建更多的局部变量,从而改变堆栈, 指针指向的位置将被那些新的 当地人。这是正确的吗?

    是的,您正确理解了这个问题。

    【讨论】:

    • 太棒了。谢谢!我只是想确保我的假设是正确的。
    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    相关资源
    最近更新 更多