如何在单个线程中管理套接字和信号量

时间:2017-12-26 12:29:15

标签: c linux

我想使用单个线程来处理套接字传入数据,并在信号量解锁时执行一些操作。根据这个帖子

Can we obtain a file descriptor for a semaphore or condition variable?

我无法使用select系统调用。现在我正在使用信号而不是select()来尝试这样的事情。但我无法摆脱可能的竞争条件。

static int         dataReady;  // Socket data ready flag
static int         fd;         // Socket file descriptor
static int32*      pldSemId;   // Semaphore identifier

void sigioHandler(int /* sig */){
    dataReady = 1;
}

void tryReceiveData(){
    disableSignals();
    int  len;
    char buf[8192];

    struct sockaddr_nl sourceaddr;
    struct iovec iov = { buf, sizeof(buf) };
    struct msghdr msg;
    struct nlmsghdr *nh;

    if (!dataReady){
        enableSignals();
        return;
    }

    msg = { &sourceaddr, sizeof(sourceaddr), &iov, 1, NULL, 0, 0 };
    len = recvmsg(fd, &msg, MSG_DONTWAIT);
    ...        

    dataReady = 0;
    enableSignals();
}

void doSemaphoreActions(){
    int r;
    sops.sem_num = 0;
    sops.sem_op = -1;
    sops.sem_flg = 0; // wait and blocked

    if (semop(*pldSemId, &sops, 1) == -1) {
        if (errno == EINTR){
            return;
        }
        // Process other possible errors
        ...
    }

    // Do something useful
    ...
}

int main(){
    // Open and configure the socket
    fd = socket(...);
    ...
    // Configure the signal handler
    signal(SIGIO, sigioHandler);
    fcntl(fd, F_SETOWN, getpid());
    fcntl(fd, F_SETFL, O_ASYNC);

    // Configure the semaphore
    ...

    while (true){
        tryReceiveData();
        // SIGIO signal may be received here so we won't
        // process socket data until the next SIGIO arrives
        // or the semaphore gets unlocked
        doSemaphoreActions();
    }
}

当线程处于“运行”状态时,有没有办法禁用信号处理程序?或者可能有更好的解决方案?

0 个答案:

没有答案