【问题标题】:Thread pool where the tasks are relatively large任务比较大的线程池
【发布时间】:2015-06-20 03:09:49
【问题描述】:

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

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

我应该如何宣布某个特定线程已完成一项任务但与该任务相关的数据仍在使用中?在队列中添加某种“正在处理”标志并让工作线程在队列工作时解锁队列是否可行?

【问题讨论】:

    标签: c multithreading


    【解决方案1】:

    修改排队结构,使排队的只是一个指向要处理的数据的指针。

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

    因此,您可以通过不在队列中使用大数据块来解决大数据块的问题——您使用小数据块,也就是指向大数据块的指针。

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

    我并不是建议生产者使用malloc(),消费者使用free()

    我的建议是组织队列,这样就不会出现生产者或消费者需要长时间锁定队列的问题。但是,如果您的队列已经是一个指针队列,我不明白您是如何遇到问题的。

    这可能归结为术语——这是造成混乱的主要原因。

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

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

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

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

    【讨论】:

    • 感谢乔纳森的回答。目前我的队列是一个指针队列,但是我在程序开始时分配了有限数量的缓冲区。如果我错了,请纠正我,但您的建议是我改为让生产者线程根据需要分配 malloc 内存,并让工作人员在完成后释放它?
    • @Jay:查看更新。请注意,如果您只是在队列上有指针,我不确定我是否理解导致您的问题的原因。您可以使用互斥锁和条件变量尽可能快地将项目添加到队列中并从队列中删除它们。您根本不会阻塞队列任何时间长度。但这也是我在答案的扩展信息中所说的。
    • 我相信我的困惑在于,一旦工作人员删除了指向所述缓冲区的任务,我如何保护我有限数量的缓冲区免受生产者的攻击,而该任务正在处理。我最初认为这种保护应该内置到任务队列中,但我应该创建第二个包含空闲缓冲区列表的队列吗?在这种情况下,生产者将从空闲缓冲区队列中弹出下一个干净的缓冲区,填充它,并将其推送到任务队列中。工作人员会将其从任务队列中弹出,处理它,然后在任务完成后将其推送到空闲队列中。
    • 你概述的内容非常符合我认为你需要的内容,是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2010-11-10
    • 2010-09-07
    • 2010-12-18
    • 2012-09-03
    • 2021-11-17
    • 2012-12-28
    相关资源
    最近更新 更多