如何重复使用线程 - pthreads c

3
我正在使用C语言的pthreads进行编程。
我有一个父线程,需要创建4个子线程,它们的id分别为0、1、2、3。当父线程获取数据时,它会将数据拆分并分配给4个不同的上下文变量,每个子线程一个。子线程必须处理这些数据,同时父线程应该等待这些线程完成。一旦这些子线程已经执行完毕,它们将在相应的上下文变量中设置输出,并等待(以便重用)。一旦父线程知道所有这些子线程都完成了这一轮,它就会计算全局输出并将其打印出来。现在,它在等待新的数据(子线程尚未被杀死,它们只是在等待)。
如果父线程获得更多的数据,则会重复上述过程-尽管使用已经创建的4个线程。
如果父线程收到一个终止命令(假设是特定类型的数据),它将指示所有子线程终止自己。现在,父线程可以终止。
我是一名硕士研究生,我遇到了上述情况的需要。我知道可以使用pthread_cond_wait、pthread_Cond_signal实现这个功能。我已经编写了代码,但它只是无限运行,我无法弄清楚原因。
我猜想,我编写的方式过于复杂。了解如何实现这一点将非常有帮助。如果需要,我可以发布一个简化版本的代码,以显示我正在尝试做什么(尽管我认为我的方法是错误的!)......
请问您如何使用pthread实现这种情况?

你可能想看一下这篇帖子,其中的答案描述了各种主从场景。还有一个答案详细介绍了如何使用POSIX。 - jogojapan
为了在四个线程完成工作后需要的同步,您可能需要查看这里:http://www.lambdacs.com/cpt/FAQ.html#Q292 - alk
2个回答

1

从您的描述中可以看出,原则上似乎没有什么问题。

您正在尝试实现的是一个工作池,我猜想,应该有很多实现方法。如果您的线程正在进行大量计算(至少需要一个CPU秒左右),这种方案就完全过度了。现代POSIX线程的实现已经足够高效,它们支持创建大量的线程,真的很多,而且开销并不会阻碍程序运行。

唯一需要注意的是,如果您的工作线程通过共享变量、互斥锁等方式进行通信(而不是通过线程的返回值),那么您需要使用属性参数来启动分离线程,即使用pthread_create

一旦您为任务实现了这样的方案,请进行测量。只有当您的分析器告诉您,在pthread例程中花费了相当多的时间时,才开始考虑实现(或使用)工作池来回收您的线程。


我的程序在使用线程池概念时将创建160000个线程。如果我不使用线程池,则此数字将增加到160万-增加了10倍。即使如此,这仍然不会影响时间吗? - The Flying Dutchman
@TheFlyingDutchman,我怎么知道呢。你没有给我们任何线索,让我们知道你的线程实际上是做什么的,它们花费了多少时间来完成应用程序任务以及有多少开销。测量一下,你就会知道了。(并请分享。) - Jens Gustedt
@TheFlyingDutchman - 如果您在池中只创建了16个工作线程,并且从未再创建更多,则永远只会有16个工作线程。 - Martin James

0
一个生产者-消费者线程,有4个线程挂在它上面。想要将这四个任务排队的线程组装了四个上下文结构体,其中包含了除其他数据之外的指向“OnComplete”函数的函数指针。然后,它将所有四个上下文提交到队列中,原子地递增一个任务计数器(taskCount)达到4,并等待事件/条件变量/信号量。
四个线程从P-C队列获取上下文并开始工作。
完成后,线程调用“OnComplete”函数指针。
在OnComplete中,线程原子地减少taskCount。如果一个线程将其减少到零,则发出事件/条件变量/信号量信号,源线程继续运行,知道所有任务都已完成。
很容易安排上下文的组装和同步等待也在任务中完成,以便允许池同时处理多个“ForkAndWait”操作以供多个请求线程使用。

我必须补充说明,在面向对象的语言中,这样的操作要容易得多。例如,最新的Java有一个“ForkAndWait”线程池类,应该可以完全做到这种事情,但是C++(甚至是C#,如果你喜欢农奴制)比纯C更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接