Linux下的信号回调执行,要注意死锁
#include <signal.h> #include <pthread.h> #include <stdio.h> #include <unistd.h> pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static lv_obj_t* gif = NULL;
void showGif() {
gif = lv_gif_create(lv_scr_active());
lv_gif_set_src(gif, "A:/opt/gif/hello.gif");
}
void signal_handler(int signum) { pthread_mutex_lock(&lock); lv_gif_set_src(gif, "A:/opt/gif/hello1.gif"); pthread_mutex_unlock(&lock); } int main(int argc, char* argv[]) { signal(SIGUSR1, signal_handler);
showGif();
int timeLen = 0; while (1) { pthread_mutex_lock(&lock); timeLen = lv_timer_handler(); pthread_mutex_unlock(&lock);
usleep(timeLen * 1000);
} }
一直对linux下的信号有点畏惧,这两天在测一个lvgl的程序时,遇到一个坑。程序的主逻辑就是在主线程中创建一个gif对象,lv_obj_t* gif = lv_gif_create,然后显示一张gif图片,lv_gif_set_src(gif, "A:/opt/gif/hello.gif")。然后进入死循环中调用lv_timer_handler来催动界面绘图。程序运行起来后,通过kill -USR1 给进程发送信号,在signal_handler中的pthread_mutex_lock会死锁。
根据网上的解释(对内核完全不熟悉),当前进程只有一个线程,在进程收到信号SIGUSR1时,会在当前主线程的上下文中执行回调函数signal_handler。也就会出现问题,while(1)中首先获取互斥锁pthread_mutex_lock,如果signal_handler被插入到lock和unlock之间,那么也就是执行两次lock,则signal_handler中的pthread_mutex_lock就会产生死锁。

浙公网安备 33010602011771号