任务相对较大的线程池

时间:2015-06-20 03:09:49

标签: c multithreading

我在C中创建了一个线程池。池中的每个线程都执行完全相同的功能。几个生产者线程使用相当标准的互斥/ cond方法将新数据放入此池的队列中。

新数据总是比较大,而且必须执行的处理量可能需要很长时间。每当我看到这样的东西被实现时,工作人员在复制所需数据或执行他们请求的任务时锁定队列。在我的情况下,这些操作中的任何一个可能需要一段时间,并且在此期间其他线程将被阻止访问队列。

我应该如何宣布某个特定线程已执行任务但是仍在使用与该任务相关的数据?在过程中添加某种“过程”是否切实可行?标记到队列并让工作线程在其工作时解锁队列?

1 个答案:

答案 0 :(得分:4)

修改排队结构,以便排队的只是指向要处理的数据的指针。

当线程需要获取作业时,它会抓取互斥锁,获取指向要执行的任务的下一个指针,可能会删除指针的队列内副本,或者确保其他线程不会处理它正在处理,然后释放互斥锁(或发出条件或其他信号)。通过指针访问大块数据;只有一个线程有指针;它在完成后会清理,但是在知道没有其他线程正在处理相同数据的情况下它会安全运行。

因此,你可以通过不在队列中使用它们来解决大块数据的问题 - 你使用很少的数据块,也就是指向大块的指针。

  

目前我的队列是一个指针队列。但是,我malloc在程序开头有限数量的缓冲区。如果我错了,请纠正我,但你的建议是,我根据需要拥有生产者线程malloc内存,并在完成时让工人free

我并不是说你让制作人使用malloc()而消费者使用free()

我建议您组织队列,以便生产者或消费者在任何延长的时间段内都不需要锁定它。但是,如果你的队列已经是一个指针队列,我首先不明白你是如何遇到问题的。

这可能归结为术语 - 非常混乱。

我想要建议的是,有一个“任务等待消耗”的队列。有时,该队列将为空;然后,消费者线程将在条件“队列不为空”上等待,并且当生产者向队列添加任务时,其中一个等待的消费者将被唤醒并将接管运行新任务。但消费者的初始步骤只是将任务从“等待消费”队列中删除。

队列上的信息必须足以确定需要做什么 - 这可能只是指向'任务描述'的指针,其中包含指向要存储数据的位置的进一步指针。从队列中删除“任务描述”应该(必须)快速,简单的操作(受互斥和条件保护)。多个线程不会同时访问给定的任务描述它指向的数据不会被其他线程访问(通常)。如果线程之间共享数据,那么必须像往常一样协调对该共享数据的并发访问。

但关键设计点是,消费者线程在操作队列时花费最少的时间阻塞其他消费者线程或生产者线程。它可以访问队列,删除队列中的第一个项目,并释放对队列的访问权限。然后它继续处理需要完成的任务 - 不受生产者或其他消费者的干扰。

同样,生产者线程准备任务描述并确保使用相关(预分配)缓冲区等 - 小心处理缓冲区的获取等。但是当任务描述准备就绪时,生产者花费一个很短的时间获取对队列的访问,将任务描述添加到队列,释放对队列的访问,发出“队列非空”状态的信号。