linux c实现线程超时退出,c – 如何在另一个线程的超时内唤醒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."
选择将wakup因为:
1)read/write availability
2)select error
3)descriptoris closed.
但是,如果没有可用数据并且select仍在超时范围内,我们如何从另一个线程唤醒select()?
[更新]
伪代码
// 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, 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, NULL, SocketReaderThread,
NULL, (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提供了一种实现此目的的方法,他的方法将套接字数据(可能是脏数据或退出消息数据)写入唤醒选择.我将进行测试并在那里更新结果.
2)另外要提一下,关闭套接字并不能保证唤醒select函数调用,请参见this post.
[UPDATE2]
做了很多测试后,这里有一些关于唤醒选择的事实:
1)如果select监视的套接字被另一个应用程序关闭,则select()调用
会立刻醒来.此后,读取或写入套接字将使用errno = 0获得返回值0
2)如果select监视的套接字被同一应用程序的另一个线程关闭,
如果没有要读取或写入的数据,则select()将在超时之前不会唤醒.选择超时后,使用errno = EBADF进行读/写操作会导致错误
(因为套接字在超时期间已被另一个线程关闭)
解决方法:
我使用基于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
#include
#include
#include
#include
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)", strerror(errno), 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成员;我甚至不确定我是否会再使用它了.
标签:c-2,linux,tcp,multithreading,sockets
来源: https://codeday.me/bug/20190529/1177712.html
linux c实现线程超时退出,c – 如何在另一个线程的超时内唤醒select()相关推荐
- 用三个线程实现生产者消费者模型,其中一个线程作为生产者,二个线程作为消费者,生产者随机生产一个时间戳或者字符串,消费者消费这个时间戳,并不能重复消费,并将其打印出来
题目要求: 用三个线程实现生产者消费者模型,其中一个线程作为生产者,二个线程作为消费者,生产者随机生产一个时间戳或者字符串,消费者消费这个时间戳,并不能重复消费,并将其打印出来.(这是一道百度面试的算 ...
- 工作中如何使用线程池的?自己如何定义一个线程池?
工作中如何使用线程池的?自己如何定义一个线程池? import java.util.concurrent.*;public class MyThreadPoolDemo {public static ...
- 关于PrintQueueCollection()类,跨线程调用错误“线程无法访问此对象,因为另一个线程拥有该对象”
使用System.Printing.PrintQueueCollection() 纸质打印机获取 _generalPrinters = new PrintQueueCollection(); pu ...
- java编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z。打印顺序为12A34B56C….5152Z。即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替
2.编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z.打印顺序为12A34B56C-.5152Z.即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替循环打印 ...
- 设计两个个线程模拟存取款操作,其中一个线程每次随机存1~1000元钱,另外一个线程取1-1000元钱,如果余额不足,则取款失败,提示余额不足。写出程序(考虑并发问题)。
设计两个个线程模拟存取款操作,其中一个线程每次随机存1~1000元钱, 另外一个线程取1-1000元钱,如果余额不足,则取款失败,提示余额不足. 写出程序(考虑并发问题). import java.u ...
- java 用户线程如何修改界面内容_java 加入一个线程、创建有响应的用户界面 。 示例代码...
javajava 加入一个线程.创建有响应的用户界面 . 示例代码 来自thinking in java 4 21章 部分代码 目录21.2.11 package org.rui.thread.con ...
- python线程暂停_在python中暂停一个线程和另一个线程
我正在研究如何在python中执行多线程(2个线程).在 我要他们中的一个一直在读串行端口.读取每个帧并将其保存到数据库中.我已经做了一个脚本来做这个.在 对于第二个,我希望它监听一个套接字端口.当它 ...
- python 线程重启_在Python中重新启动一个线程
我正在尝试为 Python 3.4中的项目制作线程飞行软件,其中我需要线程重新启动,以防在传感器读取期间发生I / O错误或其他类似的侥幸崩溃.因此,我正在制作一个看门狗来检查线程是否已经死亡并重新启 ...
- 线程退出【Linux学习】pthread_create主线程与创建的新线程之间退出关系
本篇文章个人在青岛吃饭的时候突然想到的...最近就有想写几篇关于线程退出的文章,所以回家到之后就奋笔疾书的写出来发布了 我们在一个线程中经常会创立另外的新线程,如果主线程退出,会不会影响它所创立的新线 ...
最新文章
- Linux Mint 19 安装Gnome Boxes 新建失败
- 新手必看,17 个常见的 Python 运行时错误
- php接口性能测试工具,PHP 应用性能优化指南
- 深入理解C程序内存布局
- linux glibc 编译安装,glibc的安装编译
- 向seaborn传递matplotlib绘图参数,精细地控制seaborn输出图形
- 办公技巧:Excel日常高频使用技巧,赶快收藏吧!
- Chrome 调试技巧 1
- 牛客题霸 [字符串的排列] C++题解/答案
- 【目标检测】NMS和soft-NMS详解及代码实现
- C语言基础之--sizeof()运算符的使用以及注意
- SpringMvc-HandlerMapping/RequestCondition
- 欧姆龙cp1h指令讲解_欧姆龙PLC编程指令含义及其用法
- 计算机中算术逻辑单元负责,算术逻辑单元可实现 算术逻辑单元的发展
- 如何删除双系统中的其中一个(完全删除)
- Nginx-负载均衡部署
- C#替换方向性的 Unicode 控制字符,解决无法匹配iphone 通讯录复制的手机号码问题
- 【英语学习】关于音标的汇总图分享
- centos 6.9界面中文显示英文或者英文界面改中文
- Java线程同步容易犯错的坑
热门文章
- java 通过反射得到命名空间_利用反射得到一个命名空间下的所有类,并调用?...
- dsniff 和 Ettercap 和 bettercap 详解 - 网络嗅探工具包
- Effective Java~57. 将局部变量的作用域最小化
- oracle表参数,Oracle 表的创建 及相关参数
- php保存rar,php 解压rar文件
- oracle 会话 临时表,Oracle 学习系列之二(会话与事务级临时表)
- 砥志研思SVM(三) 最优间隔分类器问题(下):软间隔SVM
- 逆向调试完成端口回包实践总结
- 现代软件工程 第三章 【软件工程师的成长】练习与讨论
- 金坛区实验幼儿园服务器不稳定,2019年金坛城区部分公办幼儿园服务区划分方案(试行)...