程序终止时清理 pthread 资源

Posted

技术标签:

【中文标题】程序终止时清理 pthread 资源【英文标题】:Clean up pthread resources when programme terminate 【发布时间】:2010-10-20 05:06:44 【问题描述】:

我已经使用 pthread 创建了一个线程。我的工作程序是一个无限循环。当我的主程序退出时,终止和清理 pthread 的所有资源的设计模式是什么?

pthread_create(&thread, NULL, worker, NULL);

void* worker(void* arg)

while(true)

 //do something



谢谢

【问题讨论】:

【参考方案1】:

我通常有一个全局变量,当你希望线程退出并从主函数加入线程时,它被初始化为 true 并设置为 false。伪代码如下:

global isRunning = true

def main:
    isRunning = true
    id1 = startThread (worker)
    id2 = startThread (worker)
    id3 = startThread (worker)
    joinThread (id1)
    joinThread (id2)
    joinThread (id3)
    exit

def worker:
    initialiseWorker()
    while isRunning:
          # something in here (or a signal handler) will
          #  set isRunning to false.
          doSomeWork()
    terminateWorker()

并确保线程及时执行该循环,以便它们能够检测到它们应该何时退出。如果他们长时间运行的作业,您还需要在doSomeWork() 内定期检查。我制定了一条一般规则,即线程应在被告知后五秒内退出。

从不从外部杀死线程。可以引入的问题太多了。全局标志方法让每个线程控制自己,因为它通常是唯一知道何时可以安全干净退出的线程。

【讨论】:

【参考方案2】:

除了检查一个开关,全局的或其他的,pthreads 有它自己的取消机制。看看pthread_cancel()、pthread_setcancelstate()、pthread_setcanceltype()、pthread_testcancel()、pthread_cleanup_push()等

基本思想是工作线程创建(或使用现有的)取消点。如果取消,则在退出之前调用线程的推送清理处理程序以清理资源。

【讨论】:

【参考方案3】:

当你的主程序退出时,所有线程也会退出。这意味着只有一个线程调用 exit()(或者如果主例程终止),那么其他线程将退出。

你不能仅仅杀死线程。如果你杀死正在工作的线程,那么最好的情况是你会发生内存泄漏,最坏的情况是你会遇到死锁。无论哪种方式,它都不漂亮。

在进程终止时清理的任何资源,将在最后一个线程退出时(或者如果任何线程调用 exit() )被清理。这包括内存(不包括共享内存,例如 posix 或 sysv)、类似文件的对象(如果没有其他进程具有打开的描述符)和一些其他类型的对象。

任何其他持久性(例如临时文件、某些类型的共享内存),您需要在退出之前或(更可靠地)在下一次运行开始时自行清理。

【讨论】:

【参考方案4】:

所有线程都应该自行退出,否则您必须手动清理它们。在第一种方法中,您将不得不使用一些全局变量,这些变量将使用锁来保护,告诉线程停止执行。这样的事情将在每个线程的 while(true) 循环中。

while(true)  
  
  GetLock(SomeGlobalVariable);  
  if(SomeGlobalVariable == true)  
     
    unlock(SomeGlobalVariable);   
    break;  
     
unlock(SomeGlobalVariable);   
 

在第二种方法中,您必须跟踪您在数组中创建的所有 threadId,然后在退出时一一杀死所有这些 id。

如果您的程序要使用许多线程,那么您最好选择线程池。在线程池中,您在程序开始时创建一些线程,然后在需要时给线程,当工作完成时,线程资源被归还。

有这方面的库。例如http://threadpool.sourceforge.net/

【讨论】:

以上是关于程序终止时清理 pthread 资源的主要内容,如果未能解决你的问题,请参考以下文章

C语言 pthread_cleanup_push()和pthread_cleanup_pop()函数(用于临界资源程序段中发生终止动作后的资源清理任务,以免造成死锁,临界区资源一般上锁)

进程是不是会在退出时自动清理 pthreads 占用的资源

您需要加入已取消的线程吗? (线程)

使用pthread时,字节仍可访问

Qt系列文章之三十四 (线程题外话---从pthread 到QThread)

Qt系列文章之三十四 (线程题外话---从pthread 到QThread)