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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux中var的作用,linux中var是什么意思

在搭建Kubernetes集群过程中&#xff0c;安装了kube-dns插件后&#xff0c;运行一个ubuntu容器&#xff0c;发现容器内无法解析集群外域名&#xff0c;一开始可以解析集群内域名&#xff0c;一段时间后也无法解析集群内域名。$ nslookup kubernetes.default Server: 10.99.0.2 …

linux redis 主从配置,redis集群(主从配置)

redis是一个key-value存储系统。和Memcached类似&#xff0c;它支持存储的value类型相对更多&#xff0c;包括string(字符串)、 list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操 作&#xff0c;而且这些操作都是…

telnet入侵linux,教你入侵RedHatLinux

此文的目的不在于教人入侵&#xff0c;而是为了提高自身的技术和加强网络管理员的安全防范意识。仅此而已!粗心大意的网络管理员应该明白&#xff1a;由于你们一个小小的操作失误可能会导致整个网络全面沦陷!本文主要是围绕LPD:网络打印服务的攻击而进行的。首先确定目标&#…

linux telnet.class,Linux telnet简单实用方法

语法telnet [-a][-e escape char][-f log file][-l user][-t term][host [port]]参数-a 企图自动登录。除了用当前已登陆的用户名以外&#xff0c;与 -l 选项相同。-e 跳过字符来进入 telnet 客户提示。-f 客户端登录的文件名-l 指定远程系统上登录用的用户名称。要求远程系统支…

linux查找文件名赋值给变量,Linux平台从文件中查找字符赋值于变量

以telnet方式登录Linux主机&#xff0c;在默认目录下用命令创建一个包含DUT wanIP的文本文件。[root] echo wanIP88.0.100.253 > ./wanIP.txt在默认目录下创建包含以下内容的shell脚本。在实际操作中&#xff0c;可能需要利用命令执行多条相同的命令。在命令后面加上"&…

linux两个数字正则,正则表达式-Linux readelf显示具有不同数字系...

我正在研究ELF文件中的一些对象,并为此目的使用了readelf.这个readelf样本显示了第3列上对象的大小(字节),在大型物体上,readelf以十六进制而不是dec打印,这打断了我的尺寸排序尝试. (排序忽略十六进制值)Num: Value Size Type Bind Vis Ndx Name1369: 808ec6e8 2048 OBJECT LO…

c++语言成绩统计系统数组,急求!!!关于学生成绩管理系统的C++ 结构体数组...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼scanf("%d",&p->data.cgrade);getchar();printf("请你输入数学成绩:");scanf("%d",&p->data.mgrade);getchar();printf("请你输入英语成绩:");scanf("%d",&p…

c语言中实现自动平移,c语言实现图像的旋转与平移

yyy(4) ty≥height&#xff0c;图象完全移出了屏幕&#xff0c;不用做任何处理。这种做法利用了位图存储的连续性&#xff0c;即同一行的象素在内存中是相邻的。利用 memcpy函数&#xff0c; 从(x ,y )&#xff0d;x )处&#xff0c;拷 0 0 点开始&#xff0c;一次可以拷贝一整…

c语言编写电子秒表程序,电子秒表C程序.doc

电子秒表C程序电子秒表程序#include#include#define uchar unsigned char#define uint unsigned intuchar code segtab[]{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x8c,0xff};uchar dbuf[3]{0,0,0};uint count;uchar sec;uchar…

c语言星空程序,C语言实现动态星空

1、/ 编译环境&#xff1a;Visual C 6.0&#xff0c;EasyX 2014冬至版/ e a s y x . c n/#include #include #include #define MAXSTAR 200/ 星星总数struct STARdoublex;inty;doublestep;intcolor;STAR starMAXSTAR;/ 初始化星星void InitStar(int i)stari.x 0;stari.y rand…

c语言stanf,stanf

1、很多问题的答案只能是“是”或“否”&#xff0c;但很多人总是通过说“我不告诉你”或者“我不知道”来逃避。2、假的事情总是显得过于巧合&#xff0c;过于圆满&#xff0c;以至于最后被揭穿。生活中的事情要都那么完美就不会有那么多人不快乐了。3、“肯定”表示有90&…

c语言循环数组赋值,for循环里边给数组赋值的难题

[Quote]/* E5.4 */#include int main(void){double data[12][5];int i0; //总共有多少个数字double row2.0; //初始数字for(i0;i<11;i){data[i][0]row;printf(“\n%d\t%.2f”,i,data[i][0]);rowrow0.1;}return 0;}[/QUOTE]我是C的初学者&#xff0c;这个程序本身没有问题&…

用c语言 c 做8位数奇校验,计算机硬件技术基础网上作业及答案

第一章概述1&#xff0e;下列叙述错误的是()A&#xff0e;目前大多数计算机结构仍属冯诺依曼结构B&#xff0e;计算机的工作原理基于“程序存储和控制”C&#xff0e;计算机的速度取决于CPU的主频&#xff0c;主频高的CPU速度快D&#xff0e;计算机系统包括硬件、软件两部分2&a…

c语言元素插入数组并排序,一数组按顺序序存放,插入一个数,按原来排序规律放在相应位置...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼前面已经有一道类似的题目为这道题做铺垫&#xff0c;我已经做出来啦。前面的题目是这样的&#xff1a;用选择法对10个数进行排序。我的做法&#xff0c;就是一个个对比扫描&#xff0c;从左到右递增。代码如下&#xff1a;#includ…

linux mpeg-4,嵌入式MPEG-4解码系统的设计与实现,嵌入式MPEG-4解码系统,嵌入式Linux,视频码流,P...

介绍了一种嵌入式高图像质量的MPEC-4视频流解码系统。该系统以嵌入式Linux作为操作系统&#xff0c;采用硬解码方式&#xff0c;把IDE接口设备或网络端口输入的MPEC-4视频码流(ES、PS和TS)转换成PAL&#xff0f;NTSC制式的电视信号输出。重点讨论了系统控制和MPEG-4解码部分的设…

android 手机壁纸源码,Android工程实现换壁纸功能【附源码】

最近工作要实现换壁纸小功能,将代码做成demo发出来没有采用zip格式换肤,因为只是更换一张图片背景1.将三张图放入drawable-hdpi,我放的是480*800的2.用sharedPreference存取皮肤的id,以便于下次启动的时候根据id来选择用哪个皮肤,在onresume()里刷新皮肤3.存到sharedPreference…

android webview 加载本地,webview加载本地资源的各种尝试

1.webview 打开sd卡上的静态html文件 &#xff0c;js文件既然放在assets文件夹下能找到&#xff0c;那能通过放在sd卡&#xff0c;能加载吗&#xff1f;答&#xff1a;事实证明&#xff0c;是没有用的。2.既然能拿到html的数据&#xff0c;那我们是不是重写html的script的tag的…

android 遍历sdcard,Android编程读取Assets所有文件(遍历每一个文件夹)并存入sdcard的方法...

本文实例讲述了Android编程读取Assets所有文件(遍历每一个文件夹)并存入sdcard的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;private void CopyAssets(String assetDir, String dir) {String[] files;try {// 获得Assets一共有几多文件files this.getResourc…

apple手表android手机,Apple Watch 4发布了,安卓手机用户如何选择呢?

Apple Watch 4发布了&#xff0c;安卓手机用户如何选择呢&#xff1f;2018年09月13日 17:40作者&#xff1a;黄页编辑&#xff1a;黄页分享一年一度的“科技界春晚”苹果新品发布在今天凌晨举行。苹果带来了新一代的智能手表——Apple Watch Series 4系列。作为“课代表”,科技…

android投屏到电视机,华为手机如何投屏到电视机上?按步骤,1分钟搞定手机投屏电视机...

现在&#xff0c;越来越多的人开始用上了华为手机&#xff0c;几乎人手一台。在平时学习、工作中&#xff0c;我也经常使用华为手机来处理、完成很多事项、任务&#xff0c;例如把手机投屏到电视机上。除了满足学习、工作需求&#xff0c;我也经常把手机投屏电视来看视频、玩游…