【问题标题】:Trying to prevent race conditions with pselect(), but signal won't interupt尝试使用 pselect() 防止竞争条件,但信号不会中断
【发布时间】:2013-05-22 22:18:39
【问题描述】:

我目前正在尝试使用套接字在 C++ 中实现服务器。我试图通过阻止 SIGINT 信号来防止竞争条件,直到它卡在阻塞 pselect 中。从那里,它应该退出,更改我的循环变量,然后退出线程。从我试图让它工作的尝试来看,它似乎到达了 pselect(),但使用我的代码并没有被中断。任何帮助表示赞赏。

监听器.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;
};

监听器.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 pselect\n";
            nReadyConnections = pselect(nSelectSocket+1, &tSelectSet,
                                    NULL, NULL, NULL, &tOriginalSignalSet);
            std::cout << "Broke out of pselect\n";
            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 被中断,而不会破坏任何可能发生的处理并允许线程优雅地关闭。 (阻塞在 pselect > 接收 SIGINT > 中断 pselect > 返回循环 > 完成并退出)

【问题讨论】:

    标签: c++ signals


    【解决方案1】:

    我已经解决了我自己的问题。因为我正在生成一个线程,所以我需要添加允许这样做的函数,以及添加一个信号处理程序,如下所示。

    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);
    

    【讨论】:

      猜你喜欢
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 2021-09-03
      相关资源
      最近更新 更多