【问题标题】:Sending multiple arguments to pthread_create()向 pthread_create() 发送多个参数
【发布时间】:2015-11-06 02:38:18
【问题描述】:

这是一个来自 The Linux Programming Interface 的程序(原代码here)。我想要做的是使用pthread_create() 向 threadFunc 发送 2 个“参数”,以实现下面列出的目标:

  1. 第一个用作 threadFunc() 中 for 循环中的迭代器;
  2. 第二个标识当前在threadFunc() 中工作的线程。所以它将是线程的某种可打印 ID。

为了实现这些目标,我创建了这个包含 2 个成员变量的结构:

struct arguments {
    int loops;
    pthread_t self;
};

并且这个函数循环“threadFuncLoops”次递增全局变量“glob”

static void * threadFunc(void *arg)
{
    struct arguments * threadFuncArgs = arg;
    int threadFuncLoops = *(arg.loops);

    for (int j = 0; j < threadFuncLoops; j++) {

        // Something happens to glob
    }

    return NULL;
}

在 main() 中,我创建了 2 个线程 (t1, t2) 并将它们发送到 threadFunc():

    struct arguments newArguments;

    s = pthread_create(&t1, NULL, threadFunc, &newArguments);

    s = pthread_create(&t2, NULL, threadFunc, &newArguments);

但是编译器在 threadFunc() 中说

request for member 'loops' in something not a structure or union

我的问题是:

  1. 为什么“循环”不在结构中?它在结构实例中不是吗?
  2. 具体如何实现目标 #2?

非常感谢。

【问题讨论】:

  • *(arg.loops); 不正确。 loops 不是指针,因此不能被引用。此外,argsvoid *,因此既不是结构指针也不是结构。在很多层面上都是错误的。应该是threadFuncArgs-&gt;loops

标签: c linux multithreading


【解决方案1】:

您正在主函数中获取newArguments地址,并将其传递给您的线程函数。这意味着它不再是struct,而是指向struct指针,因此您需要使用-&gt;

可以使用x-&gt;y 的其他方法,即(*x).y,看起来这可能是您尝试使用*(arg.loops) 实现的目标,但存在两个问题那:

  • 你试图取消引用args.loops,它不是一个指针——你应该这样做(*args).loops;和
  • 无论如何,args 是要取消引用的错误类型,您需要一个指向该结构的指针,所以它应该是 (*threadFuncArgs).loops

因此,解决此问题的一种方法是改用它:

struct arguments * threadFuncArgs = arg;
int threadFuncLoops = threadFuncArgs->loops;

另一件需要注意的事情。您传递给两个线程的指针是指向完全相同内存的指针。这意味着,如果其中一个线程发生更改,例如结构中的self 字段,它会同时更改两者。

通常,您会通过(至少)两种方式之一解决此问题:

  • 有一个结构数组,并确保每个线程都有一个唯一的,只为它自己;或
  • 让线程将其信息复制到本地存储中,但这需要重新设计以确保主函数在完成之前不会创建第二个线程。

【讨论】:

  • 我认为你需要输入 cast:struct arguments *threadFuncArgs = (struct argument *)arg;
  • @VuongHoang,不在 C 语言中。与void* 之间的转换是该语言中的隐式操作。 C++ 不多,但这个问题被标记为 C。
  • @VuongHoang:在纯 C 中,你不需要 演员表,但如果你小心的话它不会有害(但如果你不小心可能会有害) )。在 C++ 中,从 void * 到另一个指针类型的强制转换是强制性的。在 Windows 系统上,人们用作 C 编译器的编译器通常似乎确实需要强制转换——即使标准 C 不需要。
  • ,或者只是 malloc 每个线程的结构,当/如果它终止时在线程函数中释放它。
  • @paxdiablo 现在我创建了 2 个结构 newArgument1newArgument2 并将它们分别发送到 threadFunc() 以及 t1t2。结构是否必须像您所说的那样位于数组中?要获取线程 ID(目标 #2),我可以先使用threadFuncArgs-&gt;self=pthread_self();,然后再使用printf(threadFuncArgs-&gt;self); 吗?
【解决方案2】:

你必须使用“->”。将 arg.loops 替换为 threadFuncArgs->loops。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 2010-11-24
    相关资源
    最近更新 更多