问题描述
我创建了一个子进程,负责处理从父进程发送的SIGTERM
。在子进程中,我正在新线程cv
内的 condition_variable waitingForWork()
上等待。 cv
由SIGTERM
函数中的stopTheWait()
信号处理程序设置。
由于某些原因,stopTheWait()
函数无法获取lock
,并且waitingForWork()
永远等待,并且从未调用doTheCleanUp()
。
最后,父进程关闭。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex,std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
void stopTheWait(){
printf("[CHILD] Stopping the wait.. \n\n");
std::lock_guard<std::mutex> lck(mtx);
cv.notify_all();
}
void signal_callback_handler(int signum)
{
printf("[CHILD] Caught signal,trying to stop the wait... %d\n\n",signum);
stopTheWait();
}
void doTheCleanUp()/* is never called*/ {
printf("[CHILD] clean up... \n\n");
}
void waitingForWork(){
printf("[CHILD] wait for ever... \n\n");
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck);
doTheCleanUp();
printf("[CHILD] clean Up Done,Now end wait... \n\n");
exit(0);
}
int main()
{
printf("[PARENT] in parent...\n");
int pid;
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (pid == 0)
{ /* child */
signal(SIGTERM,signal_callback_handler);
std::unique_lock<std::mutex> lck(mtx);
std::thread t1(waitingForWork);
t1.join();
waitingForWork();
printf("[CHILD] wait is over...\n\n");
}
else /* parent */
{ /* pid hold id of child */
sleep(3); /* pause for 3 secs */
printf("[PARENT] sending SIGTERM\n\n");
kill(pid,SIGTERM);
sleep(3);
}
printf("[PARENT] exiting parent...\n");
sleep(1);
return 0;
}
我在下面看到印刷品。
解决方法
[support.signal] / 3 评估是信号安全的,除非它包括以下内容之一:
(3.1)—调用任何标准库函数,但无锁无原子操作和明确标识为信号安全的函数除外。
...如果信号处理程序调用包含不安全信号的评估,则它具有未定义的行为。
在信号处理程序中几乎没有人可以安全地做。 printf
,互斥量和条件变量操作都可以解决。