我正在编写一个软件来完成一项非常长的任务。为了允许中断,我们添加了一个检查点功能,该功能会定期(大约几分钟)将程序状态的镜像转储到磁盘。然而,这需要一些时间,所以我想切换到一个模型,在这个模型中,检查点被写在一个单独的线程上,而不是阻塞主要的工作线程。 (是的,我知道我需要保持线程安全。)
在我看来,有两种主要方法可以完成这项任务:
- 对于每个检查点,我
pthread_create()
一个线程,该线程将执行一次检查点函数然后终止。 - 对于每个检查点,我
pthread_cond_signal()
一个执行检查点功能然后返回等待的单个等待线程。
这两种方法都需要制作我的工作状态的原子副本并将其传递给检查点线程,并确保在我尝试另一个检查点之前成功完成检查点。
我的问题是是否有令人信服的理由使用一种方法而不是另一种方法。
最佳答案
我认为 pthreads
不适合您的要求:
无论您是为每个备份生成一个新线程还是使用线程池,都需要进行深度复制你的工作集,这是昂贵的。此外,如果您使用线程池,则可能需要大量同步。相反,有一种更简单的方法:fork()
。
子进程继承父进程的整个内存空间,但在现代操作系统上,复制是惰性的(copy on write
)。此外,您不必担心清理您启动的线程,因为 fork()
ed 子线程在终止时会释放其资源。如果您的原始程序已经是多线程的,您可能希望确保只在子程序中使用异步安全函数,但值得庆幸的是 write()
是异步安全的(open() 也是如此)
和 unlink()
)。为避免您的 child 变成僵尸,您需要在循环中调用 waitid(P_ALL, 0, siginfo_t *infop, WEXITED | WNOHANG)
直到它返回非零值或 siginfo_t *
表示 child 还没有退出。这避免了在到达下一个备份点之前 child 没有完成备份的情况下停止 parent 。
关于c - 生成运行到完成的多个线程与让单个线程等待工作之间有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31863611/