微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在另一个线程的超时时间内唤醒select

根据“人选”信息:

"On success,select() and pselect() return the number of file descrip‐ tors contained in the three returned descriptor sets which may be zero if the timeout expires before anything interesting happens. On error,-1 is returned,and errno is set appropriately; the sets and timeout become undefined,so do not rely on their contents after an error."

select将wakup,因为:

1)read/write availability 2)select error 3)descriptoris closed.

但是,如果没有可用的数据并且select仍处于超时状态,那么如何从另一个线程唤醒select()?

[更新]

代码

Unix套接.sock文件

客户端SocketInputStream.close()导致更多的资源消耗?

如何编写一个MultiPart下载C ++程序

如何find哪个函数打开socket?

SO_REUSEPORT在Linux上

// Thread blocks on Select void *SocketReadThread(void *param){ ... while(!(ReadThread*)param->ExitThread()) { struct timeval timeout; timeout.tv_sec = 60; //one minute timeout.tv_usec = 0; fd_set rds; FD_ZERO(&rds); FD_SET(sockfd,&rds)' //actually,the first parameter of select() is //ignored on windows,though on linux this parameter //should be (maximum socket value + 1) int ret = select(sockfd + 1,&rds,NULL,&timeout ); //handle the result //might break from here } return NULL; } //main Thread int main(){ //create the SocketReadThread ReaderThread* rthread = new ReaderThread; pthread_create(&pthreadid,SocketReaderThread,(void*)rthread); // do lots of things here ............................ //Now main thread wants to exit SocketReaderThread //it sets the internal state of ReadThread as true rthread->SetExitFlag(true); //but how to wake up select ?????????????????? //if SocketReaderThread currently blocks on select }

[UPDATE]

1)@trojanfoe提供了一个方法来实现这一点,他的方法套接字数据(也许脏数据或退出消息数据)来唤醒select。 我将有一个testing,并在那里更新结果。

2)另外要提到的是,closures套接字并不保证唤醒select函数调用,请看这篇文章

[UPDATE2]

经过多次testing,以下是关于醒来select:

1)如果select所监听的套接被另一个应用程序closures,select()调用将立即被唤醒。 此后,读取或写入套接字将返回值为0,且errno = 0

2)如果select所监听的套接字被同一应用程序一个线程closures,那么select()将不会被唤醒,直到超时(如果没有数据要读或写)。 select超时之后,使读/写操作导致errno = EBADF错误(因为在超时期间套接字已被另一个线程closures)

带recv-timeout的套接字:这段代码有什么问题?

如何在Windows上模拟socket.socketpair

原始套接字访问作为正常用户在Linux 2.4上

PHP socket_read()只获取stream的第一个字节

cURL请求从Unix的套接

我使用基于pipe()的事件对象:

IoEvent.h:

#pragma once class IoEvent { protected: int m_pipe[2]; bool m_ownsFDs; public: IoEvent(); // Creates a user event IoEvent(int fd); // Create a file event IoEvent(const IoEvent &other); virtual ~IoEvent(); /** * Set the event to signalled state. */ void set(); /** * Reset the event from signalled state. */ void reset(); inline int fd() const { return m_pipe[0]; } };

IoEvent.cpp:

#include "IoEvent.h" #include <string.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <poll.h> using namespace std; IoEvent::IoEvent() : m_ownsFDs(true) { if (pipe(m_pipe) < 0) throw MyException("Failed to create pipe: %s (%d)",strerror(errno),errno); if (fcntl(m_pipe[0],F_SETFL,O_NONBLOCK) < 0) throw MyException("Failed to set pipe non-blocking mode: %s (%d)",errno); } IoEvent::IoEvent(int fd) : m_ownsFDs(false) { m_pipe[0] = fd; m_pipe[1] = -1; } IoEvent::IoEvent(const IoEvent &other) { m_pipe[0] = other.m_pipe[0]; m_pipe[1] = other.m_pipe[1]; m_ownsFDs = false; } IoEvent::~IoEvent() { if (m_pipe[0] >= 0) { if (m_ownsFDs) close(m_pipe[0]); m_pipe[0] = -1; } if (m_pipe[1] >= 0) { if (m_ownsFDs) close(m_pipe[1]); m_pipe[1] = -1; } } void IoEvent::set() { if (m_ownsFDs) write(m_pipe[1],"x",1); } void IoEvent::reset() { if (m_ownsFDs) { uint8_t buf; while (read(m_pipe[0],&buf,1) == 1) ; } }

你可以沟m_ownsFDs成员; 我甚至不确定我是否再使用它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐