没有阻塞线程

时间:2016-08-16 15:16:53

标签: c linux multithreading pthreads

我已经在stackoverflow上发布了thisthis帖子,但没有人给我我想要做的事情。

在我的情况下,我想创建一个Thread,启动它并让它在没有阻塞属性的情况下运行,只要主进程运行。这个线程没有通信,没有与主进程同步,它完全独立完成了自己的工作 请考虑以下代码:

 #define DAY_PERIOD 86400 /* 3600*24 seconds */
 int main() {
   char wDir[255] = "/path/to/log/files";
   compress_logfiles(wDir);

   // do other things, this things let the main process runs all the time.
   // just segmentation fault, stackoverflow, memory overwrite or 
   // somethings like that stop it.

   return 0;
}

/* Create and launch thread */
void compress_logfiles(char *wDir)
{

    pthread_t compressfiles_th;

    if (pthread_create(&compressfiles_th, NULL, compress, wDir)) 
    {
        fprintf(stderr, "Error create compressfiles thread\n");
        return;
    }
    if (pthread_join(compressfiles_th, NULL)) 
    {
        //fprintf(stderr, "Error joining thread\n");
        return;
    }
   return;
}

void *compress(void *wDir)
{
    while(1)
    {
        // Do job to compress files
        // and sleep for one day 
        sleep(DAY_PERIOD); /* sleep one day*/
    }
    return NULL;
}

compress_logfiles 函数中使用 ptheard_join ,线程会成功压缩所有文件并且永远不会返回,因为它处于无限循环中,所以主要进程仍然一直被阻止。如果我从 compress_logfiles 函数中删除 ptheard_join ,则主进程不会被阻止,因为它不等待线程返回,但是线程会压缩一个文件并退出(有很多文件,其中一个是haundred)。

那么,有没有办法让主进程启动compressfiles_th线程并让它完成他的工作而不等待它完成或退出? 我在Linux Programmer's Manual中找到 pthread_tryjoin_np pthread_timedjoin_np ,如果我不关心返回的值,似乎 pthread_tryjoin_np 就可以完成这项工作,使用它是个好主意吗?

谢谢。

编辑1:
请注意,在调用compress_logfiles(wDir)之后,主进程是守护进程,也许守护进程会杀死主进程并重新启动它是不是问题?

编辑2:解决方案

归功于 dbush

是的,fork会导致问题, pthread_atfork()会解决问题。我进行了此更改以运行compressfiles_th而不阻止主进程:

 #define DAY_PERIOD 86400 /* 3600*24 seconds */
 char wDir[255] = "/path/to/log/files"; // global now

 // function added
void child_handler(){
    compress_logfiles(wDir); // wDir is global variable now
}

 int main() 
 {
     pthread_atfork(NULL, NULL, child_handler);
     // Daemonize the process.
     becomeDaemon(BD_NO_CHDIR & BD_NO_CLOSE_FILES & BD_NO_REOPEN_STD_FDS & BD_NO_UMASK0 & BD_MAX_CLOSE);
   // do other things, this things let the main process runs all the time.
   // just segmentation fault, stackoverflow, memory overwrite or 
   // somethings like that stop it.

   return 0;
}
在fork之后调用

child_handler()函数。 pthread_atfork

1 个答案:

答案 0 :(得分:3)

当您fork新流程时,只有调用主题重复,而不是所有主题

如果您希望进行守护,则需要先fork然后创建您的主题。

来自man page for fork

  

子进程使用单个线程创建   叫fork()。父级的整个虚拟地址空间是   复制在孩子身上,包括互斥状态,状况   变量和其他pthreads对象;使用pthread_atfork(3)   可能有助于处理这可能导致的问题。