【问题标题】:C Threads, CVI: how to return array out of thread?C 线程,CVI:如何从线程中返回数组?
【发布时间】:2015-08-27 13:22:08
【问题描述】:

我遇到了多线程程序的问题。假设我有一系列的几个整数数组(通常是 2 或 3 个),每个都由一个单独的线程处理。我设法进行了计算,但现在我想返回在我的线程中创建的已处理数组。

启动线程后,我会启动以下循环,该循环每 0.05 秒检查一次线程是否完成。这似乎工作正常。

int partsPassed = 0;

int* partsCopied;
partsCopied = (int*) malloc (numThreads * sizeof(int));

int currentCopyStatus = 0;

for (n = 0; n < numThreads; n++) {
    partsCopied[n] = 0;
}

// Loop until we copy all parts of array
while (partsPassed != numThreads) {

    // Loop through all parts of original array
    for (n = 0; n < numThreads; n++) {

        if (partsCopied[n] != 1) {

            // Check for finish of computation
            CmtGetThreadPoolFunctionAttribute(*threadPoolHandle, threadFunctionID[n], ATTR_TP_FUNCTION_EXECUTION_STATUS, &currentCopyStatus);
            if (currentCopyStatus == kCmtThreadFunctionComplete) {      // If yes, get the array and copy to original array
                CmtGetThreadPoolFunctionAttribute(*threadPoolHandle, threadFunctionID[n], ATTR_TP_FUNCTION_RETURN_VALUE, imageThreadPart[n]);
                copyStaticThreadResults(imageRecPart[n]->nrRowStart, imageRecPart[n]->nrRowEnd, imageThreadPart[n]);
                partsCopied[n] = 1; // Copy flag display
                partsPassed++;      // Count all fragments
            }
        }
    }

    Delay(0.05);

}

问题在于,根据文档,我只能从线程中得到一个 int。当我尝试使用以下函数时,这会导致失败 - 我尝试获取 int**(存储在 imageThreadPart[n] 中的二维数组)并且该函数强制我传递 int*。

CmtGetThreadPoolFunctionAttribute(*threadPoolHandle, threadFunctionID[n], ATTR_TP_FUNCTION_RETURN_VALUE, imageThreadPart[n]);

1.是否可以使用这个函数来获取这个数组?

2。这可能是一个长镜头,但是否可以使用以下函数的回调复制该数组并将线程返回的值直接传递给该回调?

CmtScheduleThreadPoolFunctionAdv (DEFAULT_THREAD_POOL_HANDLE, 
                                   myThreadFunction, // thread function
                                   imageRecPart[n], // my data
                                   THREAD_PRIORITY_TIME_CRITICAL, 
                                   copyThreadResults, // my callback
                                   EVENT_TP_THREAD_FUNCTION_END,
                                   NULL,  // data for callback - but how to pass it from thread here?!
                                   CmtGetCurrentThreadID(),
                                   &threadFunctionID[n]);

【问题讨论】:

  • 请注意,线程不能“返回”某些东西,因为它没有被“调用”(两者都与应用程序有关,而不是线程库)。使用线程时不要轮询!在你的主线程中使用一个队列来收集所有已完成线程的数据。或者,如果数据已由主线程拥有,则计数信号量将起作用。
  • @Olaf 感谢您的回复。我的印象是,当我传递函数和结构句柄时,库会让我通过复制返回值或任何其他方式来获取结果。在继续之前,我应该阅读更多关于它的内容并尝试一些更简单的示例。有tutorial 和一些examples,但它们倾向于简单地修改单个控件或简单、独立的值。有没有其他参考资料?我真的很感激。
  • "我印象深刻......" 只是一个简单的思想实验:如果你调用函数来启动线程:它是否在启动的线程仍在运行时返回? - 是的。那么,如何,何时 - 以及 where - 您是否将“结果”放入启动另一个步骤的线程中?欢迎来到异步(和并行)编程的奇妙世界。请系好安全带,周围都是焦油坑等着不知情的人;-)(OTOH如果做得对,真的很迷人)。

标签: c arrays multithreading cvi


【解决方案1】:

所有线程共享相同的内存空间,因此您可以将数组复制到共享内存中的已知位置(可能是传递给线程过程的位置,可能是全局变量,也可能是线程自己分配的缓冲区并传递一个指针)。请注意,为了确保您的数据更新在通知已写入之前到达其他 CPU 内核,您希望使用具有memory_order_release 语义的原子状态变量或自旋锁之类的东西。

【讨论】:

    【解决方案2】:

    我一直在使用 DefineThreadSafeScalarVar 和 DefineThreadSafeArrayVar 宏来简化多线程变量处理。可能值得做类似的事情

    DefineThreadSafeArrayVar(int, partsCopied, MAX_NUM_THREADS, 0);

    定义您的数组(其中 MAX_NUM_THREADS 只是您的程序允许的最大线程数 - 这必须在编译时设置)

    然后是 GetPointerTopartsCopied() 和 ReleasePointerTopartsCopied() 函数来处理您的变量访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      相关资源
      最近更新 更多