2015-11-06 51 views
4

这是一个来自Linux编程接口(原代码here)的程序。我所试图做的是使用pthread_create()下面列出的目标送2“论据”来的ThreadFunc:发送多个参数到pthread_create()

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

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

struct arguments { 
    int loops; 
    pthread_t self; 
}; 

而这个函数循环“threadFuncLoops”次递增全局变量“水珠”

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; 
} 

在主()我创建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?

非常感谢。

+1

'*(arg.loops);'不正确。 'loop'不是一个指针,所以不能被指针化。此外,'args'是一个'void *',所以不是一个结构体指针或结构体。这在许多层面上都是错误的。它应该是'threadFuncArgs-> loops'。 – kaylum

回答

2

您在主函数中将地址替换为newArguments并将其传递给您的线程函数。这意味着它不再是struct,而是指针struct,因此您将需要使用->

可以用做x->y,这是(*x).y,它看起来像可能是你试图实现与*(arg.loops)的其他方式,但有两个问题是:

  • 你”重新尝试解除引用​​3210这不是一个指针 - 你应该做(*args).loops;和
  • args无论如何是错误的类型,你需要一个指向结构的指针,所以它将是(*threadFuncArgs).loops

因此,要解决这个问题的方法之一是使用它代替:

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

的另一件事看出来。你传递给两个线程的指针是一个指向的内存完全相同的。这意味着,如果其中一个线程发生变化,例如结构中的self字段发生变化,则它将更改为

通常情况下,你会在(至少)两种方式解决这个问题:

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

我认为你需要输入cast:'struct arguments * threadFuncArgs =(struct argument *)arg;' –

+2

@VuongHoang,不在C中。从/ void *中执行是对该语言的隐式操作。 C++没有那么多,但是这个问题被标记为C. – paxdiablo

+0

@VongHoang:在纯粹的C中,你不需要对演员进行必要的控制,尽管如果你非常小心的话不会伤害(但是如果你不小心可能会造成伤害)。在C++中,从'void *'强制转换为另一种指针类型。在Windows系统上,通常看起来编译器人员使用C编译器确实需要强制转换 - 即使标准C不支持。 –

1

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