c - 没有阻塞线程

标签 c linux multithreading pthreads

我已阅读 thisthis在 stackoverflow 上发帖,但没有人给我我想做的事情。

在我的例子中,我想创建一个线程,启动它并让它在没有阻塞状态的情况下运行,只要主进程运行。这个线程与主进程没有通信,没有同步,它完全独立地完成他的工作。
考虑这段代码:

 #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,线程成功压缩所有文件并且永远不会返回,因为它处于无限while循环中,所以main进程仍然一直阻塞。如果我从 compress_logfiles 函数中删除 ptheard_join,主进程不会被阻塞,因为它不等待线程返回,但线程压缩一个文件并退出(有很多文件,大约一个)。

那么,有没有办法让主进程启动 compressfiles_th 线程,让它完成自己的工作,而不用等待它完成或退出? 我在 Linux Programmer's Manual 中找到了 pthread_tryjoin_nppthread_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;
}

child_handler() 函数在 fork 后被调用。 pthread_atfork

最佳答案

当您fork 一个新进程时,只有调用线程 被复制,而不是所有线程

如果你想守护进程,你需要先fork然后创建你的线程。

来自man page for fork :

The child process is created with a single thread--the one that called fork(). The entire virtual address space of the parent is replicated in the child, including the states of mutexes, condition variables, and other pthreads objects; the use of pthread_atfork(3) may be helpful for dealing with problems that this can cause.

关于c - 没有阻塞线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38978606/

相关文章:

c - 如何在不知道矩阵大小且无需多次读取的情况下从文件加载矩阵?

c - 如何使用 Intel 内在函数重新排序 128 位 vector ?

json - 如何使用 awk/sed 在两行之间添加新的文本行? (在文件中)

java - 如何为 Linux 打包游戏?

java - 给一个C++类foo,里面有一个synchronized方法。如何保证synchronized方法只被一个线程访问

C - 内存分配,为什么*符号前后出现

c++ - 如何测试是否定义了只能通过#define 宏访问的标识符?

linux - Cron 压缩文件

multithreading - 使用 3 个条件变量同步 3 个线程

multithreading - 功能语言中的并行性