本文介绍了如何使选择块文件描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个线程的过程。一个线程,线程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()规范,特别是当它说一下:

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.

这篇关于如何使选择块文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 01:46