我有一个有两个线程的进程。一个线程,线程 A,将设置 timerfd 计时器,而另一个线程,线程 B,将对这些计时器执行“选择”。一旦计时器到期,线程 B 将向线程 A 指示这一点。
要添加计时器,线程 A 将创建一个新计时器,然后它会唤醒线程 B 以将此计时器包含在其对 select 的调用中。我正试图通过使用文件描述符来唤醒线程 B。然后,线程 B 将在该 FD 上调用 select,并且所有 FD 都通过对 timerfd 的调用返回。
问题是我无法设法创建一个我可以控制的 FD,以便它会在我想要的时候导致 select 阻塞或返回。
我尝试将 shm_open 与 fcntl 调用一起使用,并且我尝试仅在文件上使用 open,但它们都不会导致 select 阻塞。我所有的尝试都会导致 select 立即返回。有什么方法可以创建一个会导致 select 阻塞的 FD,直到我以某种方式更新该 FD?
尝试 1 - 使用 shm_open 创建一个 FD 并使用 fcntl 设置读锁:
从线程 A 创建 FD。
if((wakeUpFd = shm_open("/wakeup", O_RDWR|O_CREAT|O_TRUNC, 0)) == -1)
printf("Failed to open /wakeup, Errno = %d\n", errno);
else
{
fcntl(wakeUpFd, F_SETLK, F_RDLCK);
}
从线程 A 添加计时器。
#create a timer and add it to a list
/* wake up timer thread */
fcntl(wakeUpFd, F_SETLK, ~F_RDLCK);
唤醒线程 B
#when select returns
if(FD_ISSET(wakeUpFd, &timerSet))
{
fcntl(wakeUpFd, F_SETLK, F_RDLCK);
}
#check all other timer FD's
尝试 2 - 使用 shm_open 并向其读取/写入数据:
从线程 A 创建 FD。
if((wakeUpFd = shm_open("/wakeup", O_RDWR|O_CREAT|O_TRUNC, 0)) == -1)
printf("Failed to open /wakeup, Errno = %d\n", errno);
else
{
if(ftruncate(wakeUpFd, 2) == -1)
{
printf("Failed with ftruncate, Errno = %d\n", errno);
}
}
从线程 A 添加计时器。
#create a timer and add it to a list
/* wake up timer thread */
if(write(wakeUpFd, wakeUpStr, 1) != 1)
printf("Failed to write to wakeUpFd\n");
唤醒线程 B
#when select returns
if(FD_ISSET(wakeUpFd, &timerSet))
{
read(wakeUpFd, wakeUpBuf, 10);
}
#check all other timer FD's
Try 3 - 与 Try 2 几乎相同,但使用 open 而不是 shm_open。
尝试 4 - 与尝试 1 相同,但使用 fcntl(wakeUpFd, F_SETFL, ~O_NONBLOCK) 而不是 fcntl(wakeUpFd, F_SETLK, ~F_RDLCK)