尝试使用 pselect() 阻止竞争条件,但信号不会中断
Trying to prevent race conditions with pselect(), but signal won't interupt
我目前正在尝试使用套接字在c++中实现服务器。我试图通过阻塞SIGINT信号来防止竞争条件,直到它被卡在阻塞的pselect中。从那里,它应该退出,改变我的循环变量,然后退出线程。从我尝试使其工作来看,它似乎到达了pselect(),但使用我的代码不会中断它。如有任何帮助,不胜感激。
Listener.h:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
class CListener
{
public:
CListener();
void quitListener(void);
private:
void* InitListener(void);
static void* StartListenerThread(void* context);
static bool mbListening;
pthread_t mtThreadID;
};
Listener.cpp
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include "Listener.h"
bool CListener::mbListening = true;
CListener::CListener()
{
mbListening = true;
mtThreadID = 0;
pthread_create(&mtThreadID, NULL, &CListener::StartListenerThread, this);
}
void* CListener::StartListenerThread(void* context)
{
return ((CListener*)context)->InitListener();
}
void* CListener::InitListener()
{
sigset_t tSignalSet;
sigset_t tOriginalSignalSet;
sigemptyset(&tSignalSet);
sigaddset(&tSignalSet, SIGINT);
sigprocmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);
FD_ZERO(&tConnectionSet);
FD_SET(0, &tConnectionSet);
while(mbListening)
{
tSelectSet = tConnectionSet;
std::cout << "Reached pselectn";
nReadyConnections = pselect(nSelectSocket+1, &tSelectSet,
NULL, NULL, NULL, &tOriginalSignalSet);
std::cout << "Broke out of pselectn";
if(nReadyConnections < 0 && errno == EINTR)
{
mbListening = false;
}
}
pthread_exit(NULL);
return NULL;
}
void CListener::quitListener()
{
raise(SIGINT);
}
只要我正确地复制了所有内容手指交叉你应该可以运行:
CListener tListener = CListener();
usleep(20000);
tListener.quitListener();
,输出应显示在终端中。我的最终目标是允许pselect被中断,而不会中断后续的任何处理,并允许线程优雅地关闭。(block at pselect> receive SIGINT> interrupt pselect> return to loop> finish and exit)
我已经解决了自己的问题。因为我正在生成一个线程,所以我需要添加允许它的函数,以及添加一个信号处理程序,如下所示。
void CListener::quitListener()
{
pthread_kill(mtThreadID,SIGINT);
}
void CListener::installSIGINTHandler()
{
signal(SIGINT, CListener::SIGINTHandler);
}
void CListener::SIGINTHandler(int signo)
{
mbListening = false;
}
并且需要将sig掩码设置更改为:
pthread_sigmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- Qt VTK交互风格的信号到小部件
- 在没有太多条件句的情况下,我如何避免被零除
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 在条件变量中触发错误信号的频率是多少
- C/C++ 在条件和阻止呼叫之间收到信号情报
- 具有条件的信号和插槽
- QT条件信号发射效率
- 信号在条件变量上而无需锁定锁
- 如何在没有条件变量的情况下阻止线程中的操作,并在Linux中根据信号恢复操作
- 在POSIX中,我可以保存信号以供调用条件等待的其他线程使用吗.(这些线程来自同一进程)
- 在发出等待条件变量的信号后,线程何时获取锁?是什么决定了它
- Pthread 条件变量即使设置为 PTHREAD_PROCESS_SHARED,也不会发出信号
- 是否有其他方法可以使用条件变量捕获可能错过的信号
- 与linux信号/条件变量相比,缓存一致性开销
- 尝试使用 pselect() 阻止竞争条件,但信号不会中断
- 互斥条件信号环路是如何工作的
- 如何在信号槽中设置等待条件
- 信号量、互斥体和条件变量的选择
- c++11在信号处理程序中使用条件变量