我想使用单个线程来处理套接字传入数据,并在信号量解锁时执行一些操作。根据这个帖子
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();
}
}
当线程处于“运行”状态时,有没有办法禁用信号处理程序?或者可能有更好的解决方案?