微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用pthread_sigmask从信号保护sem_wait

我有一个库,通过第三方库访问硬件资源(SPI)。 我的库,反过来SPI资源,由多个进程访问,所以我需要用信号locking资源,锁function如下:

static int spi_lock(void) { struct timespec ts; if (clock_gettime(CLOCK_REALTIME,&ts) == -1) { syslog(LOG_ERR,"Failed to read clock: %sn",SPISEM,strerror(errno)); return 3; } ts.tv_sec += 5; if (sem_timedwait(bcoms->spisem,"timed out trying to acquire %s: %sn",strerror(errno)); return 1; } return 0; } static int spi_unlock(void) { int ret = 1; if (sem_post(bcoms->spisem)) { syslog(LOG_ERR,"Failed to release %s: %sn",strerror(errno)); goto done; } ret = 0; done: return ret; }

现在我的问题是在守护进程中使用库,并通过kill信号停止守护进程。 有时我拿着信号锁,因此服务器无法成功重启,因为锁是永久占用的。 要解决这个问题,我试图阻止如下所示的信号(我正在等待硬件在atm上testing):

static int spi_lock(void) { sigset_t nset; struct timespec ts; sigfillset(&nset); sigprocmask(SIG_BLOCK,&nset,NULL); if (clock_gettime(CLOCK_REALTIME,strerror(errno)); return 3; } ts.tv_sec += 5; // 5 seconds to acquire the semaphore is HEAPS,so we better bloody get it !!! if (sem_timedwait(bcoms->spisem,strerror(errno)); return 1; } return 0; } static int spi_unlock(void) { sigset_t nset; int ret = 1; if (sem_post(bcoms->spisem)) { syslog(LOG_ERR,strerror(errno)); goto done; } sigfillset(&nset); sigprocmask(SIG_UNBLOCK,NULL); ret = 0; done: return ret; }

但是在阅读sigprocmask()的手册页时,它说在multithreading系统中使用pthread_sigmask(),而我想要保护的服务器之一是multithreading的。 我不明白的是如果我在库中使用pthread_sigmask(),并且主父线程产生一个SPI读取线程,使用我的库中的这些locking函数,读取线程将被保护,但不能主线程仍然收到杀死信号,并拿下守护进程,而我拿着互斥信号禁用读取线程让我不在哪里? 如果有的话,是否有更好的解决这个locking问题?

谢谢。

在debugging使用GDB的核心转储时知道谁是inheritance者

在stringC#中提取date?

什么时候WM_PAINT被调用

确定是否从EXE或DLL调用调用

如何确定一首歌曲使用winmm.dll多长时间?

在内核源代码添加printk语句后,Linux引导挂起

在Windows上混合使用Qt和Objective-C

使用Windows API读取文件

如何检测Windows 64位的cpu速度?

time_t的最大值(struct timespec)

我不认为你的方法会起作用。 您不能阻止SIGKILL或SIGSTOP。 除非你说这个守护进程正在获得一个不同的信号(比如SIGHUP)。 但即使如此,我认为阻止来自图书馆电话的所有信号是不好的做法。 这可能会对通话应用程序造成不利影响。 例如,应用程序可能依赖于特定的信号,并且缺少任何这样的信号可能导致其不正确地运行。

事实证明,使用信号量可能不是一个简单的方法解决你的问题。 所以另一种方法是使用“群”来代替。 这解决了你的问题,因为它是基于打开的文件描述符。 如果一个进程死于一个群,相关的文件描述符将被自动关闭,从而释放这个群。

事实上,你已经正确地分析了这个问题 – 屏蔽信号并不能保护你。 屏蔽信号并不是阻止进程以共享数据(如文件或共享信号量)处于不一致状态的正确工具。

你可能应该做的,如果你想退出某些信号优雅,程序安装信号处理程序来捕捉终止请求,并将其馈送到正常的程序逻辑。 有几种方法可以使用:

通过管道将终止请求发送给您自己。 如果你的程序是围绕一个可以等待管道输入的poll循环来构造的,

使用sem_post (一个异步信号安全同步功能)将信号报告给程序的其余部分。

从主线程开始一个专用的信号处理线程,然后阻塞主线程中的所有信号(并继承所有其他新线程)。 这个线程可以做for(;;) pause(); 并且由于pause是异步信号安全的,因此可以从信号处理程序调用所需的任何函数包括与其他线程同步所需的pthread同步函数

请注意,这种方法仍然不是“完美的”,因为你永远不能捕捉或阻止SIGKILL 。 如果用户决定用SIGKILL杀死你的进程( kill -9 ),那么信号量可能会处于一个糟糕的状态,而你却无能为力。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐