这是来自Linux编程接口(interface)的程序(原始代码here)。我想做的是使用pthread_create()为以下列出的目标向threadFunc发送2个“参数”:

  • 第一个在threadFunc()中的for循环中充当迭代器;
  • 第二个代码标识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
    

    我的问题是:
  • 为什么“循环”不在结构中?是在struct实例中吗?
  • 如何准确实现目标2?

  • 非常感谢你。

    最佳答案

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

    您可以使用其他方法来完成x->y,即(*x).y,看来这可能正是您尝试使用*(arg.loops)实现的,但这样做有两个问题:

  • 您正在尝试取消引用不是指针的args.loops -您应该执行(*args).loops;和
  • args是错误的类型,无论如何要取消引用,您需要一个指向结构的指针,因此它将是(*threadFuncArgs).loops

  • 因此,解决此问题的一种方法是改用此方法:
    struct arguments * threadFuncArgs = arg;
    int threadFuncLoops = threadFuncArgs->loops;
    

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

    通常,您可以通过(至少)两种方式之一来解决此问题:
  • 具有一系列结构,并确保每个线程仅针对自身获得一个唯一的线程;或
  • 让线程将其信息复制到本地存储中,尽管这需要进行一些重新设计,以确保main函数在完成此操作之前不会创建第二个线程。
  • 10-08 05:18