Perl 中的线程同步/调度
我有一个 perl 对象,其中有一些函数。每个函数从主程序中调用一次。我想并行运行一些函数以节省时间。我无法同时运行所有函数,因为某些函数依赖于先前函数的结果。
我想到了这样的事情:
- 对于每个函数,保留一个初始化为 false 的标志,并在函数结束时将其设置为 true (例如,
func1
中的最后一行将是$is_func1_done = 1 )。
用一个循环启动每个函数,该循环等待直到它所依赖的函数的所有标志都为 true。例如:如果
<前><代码> sub func1 { while (!($is_func2_done && $is_func3_done)) { # 什么都不做 } # 做工作 }func1
依赖于func2
和func3
则:
那么我可以立即为每个函数启动一个线程,但每个函数的实际工作功能只有在准备就绪时才会启动。这有道理吗?我需要在旗帜上加锁吗?使用这样的 while 循环常见吗? -- 我想到了“忙等待”这个词……也许我的大部分 CPU 时间都会花在这些 while
上?有没有更标准的解决方案?
I have a perl object with a few functions in it. Each functions is called once from the main program. I would like to run some of the functions in parallel to save time. I can't run all of them together since some functions depend on the results of previous functions.
I thought of something like this:
- For each function keep a flag that is initialized to false and is set to true by the function when it ends (e.g. the last line in
func1
would be$is_func1_done = 1
). Start each function with a loop that waits until all the flags of the functions it depends on are true. For example: if
func1
depends onfunc2
andfunc3
then:sub func1 { while (!($is_func2_done && $is_func3_done)) { # do nothing } # do work }
Then I can start immediately a thread for each function, but the actual work of each function will start only when it's ready. Does this make sense? Do I need any locks here on the flags? Is using such while
loops common? -- the term busy waiting comes to mind... maybe most of my CPU time will be spent on these while
s? Is there a more standard solution to this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的 - 每个任务都知道其先决条件,并在执行之前等待它们满足。它是众多有效设计之一,尽管您可能会发现随着任务数量的增加以及它们的相互依赖性变得更加复杂而难以扩展。
是的。这些标志需要共享,以便一个线程可以操作它们,另一个线程可以看到它,并且共享变量需要被
lock()
ed 才能安全使用。遗憾的是,是的,但是请不要这样做。 Perl 中的共享变量可以用作条件变量,线程可以通过它发送通知彼此之间:
当您
cond_wait
时,共享变量将被解锁并且您的线程将进入睡眠状态。无需忙循环。$thr->join
,如 Sinan 建议< /a> 是等待特定线程完成运行的一种简单而自然的方法。 Thread::Semaphore 可以提供类似但更复杂的功能(并且,有帮助的是,可以被初始化为小于零的值)。 “等待这 5 个线程完成某事”的常见需求可以通过 线程来实现: :屏障。 TMTOWTDI。Yes - each task knows its preconditions, and waits for them to be met before executing. It's one of a number of valid designs, though you might find it difficult to scale as the number of tasks grow and their interdependencies grow more complex.
Yes. The flags need to be shared, so that one thread can manipulate them and another see it, and shared variables need to be
lock()
ed to be used safely.Sadly yes, but Don't Do That, Please. Shared variables in perl can serve as condition variables through which threads can send notifications to one another:
When you
cond_wait
, the shared variable is unlocked and your thread is put to sleep. No need to busy loop.$thr->join
, as Sinan suggests, is an easy and natural way to wait for a specific thread to finish running. Thread::Semaphore can serve a similar but more complex function (and, helpfully, can be initialized to values less than zero). A common need to "wait for these 5 threads to finish something" can be achieved with a Thread::Barrier. TMTOWTDI.您应该使用
$thr->join
来等待线程完成。例如:
我不知道使用这样的
while
循环是否常见:我不会。You should use
$thr->join
to wait for a thread to finish.For example:
I don't know if it is common to use such
while
loops: I would not.