问题描述
我有两个线程的过程。一个线程,线程A,将设立timerfd计时器和其他线程,线程B,将这些计时器进行选择。一旦计时器到期线程B将表明这线程A
I have a process with two threads. One thread, thread A, will set up timerfd timers and the other thread, thread B, will perform 'select' on those timers. Once a timer expires thread B will indicate this to thread A.
要添加计时器,线程A将创建一个新的计时器,然后它会唤醒线程B,包括在其呼叫选择此计时器。我试图用一个文件描述符只是为了这个目的来唤醒线程B。然后线程B将要求选择的FD和所有FD的通过调用返回timerfd。
To add timers, thread A will create a new timer and then it will wake up thread B to include this timer in its call to select. I'm trying to wake up thread B by using a file descriptor just for that purpose. Thread B would then call select on that FD and all the FD's returned by calls to timerfd.
问题是,我不能设法创建一个FD,我可以在某种程度上控制,这样就会使选择阻止或返回,当我想要的。
The problem is that I cannot manage to create a FD that I can control in a way so that it will cause select to block, or return, when I want.
我曾尝试使用的shm_open与调用了fcntl,我已经试过只使用开放上的文件,但没有人会选择造成阻塞。我的所有尝试将导致选择立即返回。有什么办法来创建一个FD,这将导致选择阻塞,直到我更新FD不知何故?
I have tried to use shm_open with calls to fcntl, and i have tried to just use open on a file, but none of them will cause select to block. All my attempts causes select to return immediately. Is there any way to create a FD that will cause select to block until I update that FD somehow?
尝试1 - 用的shm_open创建一个FD和使用fcntl设置读锁:
Try 1 - Create a FD with shm_open and use fcntl to set read lock:
从线程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添加计时器。
Add timer from thread 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和读/写数据到它:
Try 2 - Use shm_open and read/write data to it:
从线程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添加计时器。
Add timer from thread 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
3尝试 - pretty一样一样的尝试2,但使用开放式的,而不是的shm_open
Try 3 - Pretty much the same as Try 2 but use open instead of shm_open.
4尝试 - 同尝试1,但的fcntl(wakeUpFd,F_SETFL,O_NONBLOCK〜)代替的fcntl(wakeUpFd,F_SETLK,〜F_RDLCK)
Try 4 - Same as Try 1 but with fcntl(wakeUpFd, F_SETFL, ~O_NONBLOCK) instead of the fcntl(wakeUpFd, F_SETLK, ~F_RDLCK)
推荐答案
阅读<$c$c>select()$c$c>规范,特别是当它说一下:
Read the select()
specification, especially the bit where it says:
文件描述符应始终选择如此准备好读,准备写和错误条件。
您不能对普通文件的文件描述符选择()
块。你必须有一个管道,或插座,或者类似的规定,如该文件,你选择()
在
You can't make select()
block on file descriptors for regular files. You'd have to have a pipe, or socket, or something along those lines, as the file you select()
on.
这篇关于如何使选择块文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!