日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux c实现线程超时退出,c – 如何在另一个线程的超时内唤醒select()

發(fā)布時間:2024/7/23 linux 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux c实现线程超时退出,c – 如何在另一个线程的超时内唤醒select() 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

根據(jù)“男人選擇”信息:

"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因?yàn)?#xff1a;

1)read/write availability

2)select error

3)descriptoris closed.

但是,如果沒有可用數(shù)據(jù)并且select仍在超時范圍內(nèi),我們?nèi)绾螐牧硪粋€線程喚醒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提供了一種實(shí)現(xiàn)此目的的方法,他的方法將套接字?jǐn)?shù)據(jù)(可能是臟數(shù)據(jù)或退出消息數(shù)據(jù))寫入喚醒選擇.我將進(jìn)行測試并在那里更新結(jié)果.

2)另外要提一下,關(guān)閉套接字并不能保證喚醒select函數(shù)調(diào)用,請參見this post.

[UPDATE2]

做了很多測試后,這里有一些關(guān)于喚醒選擇的事實(shí):

1)如果select監(jiān)視的套接字被另一個應(yīng)用程序關(guān)閉,則select()調(diào)用

會立刻醒來.此后,讀取或?qū)懭胩捉幼謱⑹褂胑rrno = 0獲得返回值0

2)如果select監(jiān)視的套接字被同一應(yīng)用程序的另一個線程關(guān)閉,

如果沒有要讀取或?qū)懭氲臄?shù)據(jù),則select()將在超時之前不會喚醒.選擇超時后,使用errno = EBADF進(jìn)行讀/寫操作會導(dǎo)致錯誤

(因?yàn)樘捉幼衷诔瑫r期間已被另一個線程關(guān)閉)

解決方法:

我使用基于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成員;我甚至不確定我是否會再使用它了.

標(biāo)簽:c-2,linux,tcp,multithreading,sockets

來源: https://codeday.me/bug/20190529/1177712.html

總結(jié)

以上是生活随笔為你收集整理的linux c实现线程超时退出,c – 如何在另一个线程的超时内唤醒select()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。