使用线程在C语言编程时,在Linux shell中,我试图减少线程开销,基本上降低CPU时间(并使其更高效)。
现在在程序中正在创建许多线程,并且需要在它终止之前完成一项工作。由于相互排斥,只有一个线程可以同时完成这项工作。
我知道线程在开始作业之前需要多长时间才能完成作业
其他线程必须等待有线程执行该作业。他们检查是否可以完成工作的方式是满足条件变量。
对于等待线程,如果他们等待使用该条件变量,使用此特定代码等待(a,b,c和d只是任意的东西,这只是一个例子):
while (a == b || c != d){
pthread_cond_wait(&open, &mylock);
}
这有多高效?在pthread_cond_wait
代码中发生了什么?是不是一个循环(幕后)不断检查条件变量?
另外,既然我知道一个线程需要多长时间,那么我是否更有效率地首先执行关于最短作业的调度策略?或者这没关系,因为在完成这项工作的任何线程组合中,程序将花费相同的时间来完成。换句话说,使用最短作业首先降低其他线程进行等待的CPU开销吗?由于最短的工作似乎首先降低了等待时间。
答案 0 :(得分:4)
使用单个线程解决您的问题,然后向我们寻求帮助,以确定暴露并行化的最佳位置,如果您还不能看到需要最少锁定的途径。要使用的最佳线程数取决于您使用的计算机。使用多于n + 1个线程没有多大意义,其中n是程序可用的处理器/核心数。为了减少线程创建开销,为每个线程提供多个作业是个好主意。
以下是对您的澄清编辑的回应:
现在在程序中正在创建大量线程并需要执行 在它终止之前的工作。只有一个线程可以同时完成这项工作 时间因为相互排斥。
没有。如上所述,最多应创建n + 1个线程。互斥是什么意思?我认为互斥是“只有一个线程在其工作队列中包含任务x”。这意味着没有其他线程需要锁定任务x。
其他线程必须等待有线程执行该作业。该 他们检查是否可以完成工作的方式是条件变量 满足。
为每个线程提供一个独立的任务列表来完成。如果作业x是作业y的先决条件,则作业x和作业y理想地位于同一列表中,以便线程不必处理任一作业上的线程互斥对象。你有没有探索过这条大道?
while(a == b || c!= d){ pthread_cond_wait(& open,& mylock); } 这有多高效?在pthread_cond_wait代码中发生了什么? 这是一个不断检查的循环(幕后) 条件变量?
为了避免未定义的行为,mylock必须在调用pthread_cond_wait之前被当前线程锁定,所以我假设你的代码在输入这个循环之前调用pthread_mutex_lock来获取mylock锁。
while (a == b || c != d)
。因此,您也可以运行将作业存储在优先级队列中的单线程代码。至少你不会有不必要的和过多的上下文切换。正如我之前所说,“用一个线程解决你的问题”。在有针对性地测量优化之前,您无法对优化保存的时间做出有意义的陈述。
此外,因为我知道线程将要花多长时间,所以更多 我有效地执行关于最短作业的调度策略 第一?或者这不重要,因为在线程的任何组合中 在完成这项工作后,该计划将花费相同的时间 完。换句话说,使用最短作业首先降低CPU 等待其他线程的开销?由于工作时间最短 首先似乎是等待时间缩短了。
如果您要强制执行调度策略,请在单线程项目中执行。如果您认为并发性将帮助您快速解决问题,那么将完成的单线程项目暴露给并发并派生测试以验证您的信念。我建议以线程不必共享工作的方式公开并发。
答案 1 :(得分:2)
Pthread原语通常相当有效;阻塞的东西通常在阻塞时不消耗或忽略不计的CPU时间。如果您遇到性能问题,请先查看其他地方。
不要担心调度策略。如果您的应用程序的设计使得一次只能运行一个线程,那么在承担所有成本的同时,您将失去首先进行线程化的大部分好处。 (如果你没有强加所有的费用,比如锁定共享变量,因为一次只运行一个线程,你就会在路上遇到麻烦。)