3 回答
TA贡献1836条经验 获得超4个赞
您可以使用管道来通知线程您希望其退出。然后,您可以select()在管道和监听套接字上进行选择的呼叫。
例如(编译但未完全测试):
// NotifyPipe.h
#ifndef NOTIFYPIPE_H_INCLUDED
#define NOTIFYPIPE_H_INCLUDED
class NotifyPipe
{
int m_receiveFd;
int m_sendFd;
public:
NotifyPipe();
virtual ~NotifyPipe();
int receiverFd();
void notify();
};
#endif // NOTIFYPIPE_H_INCLUDED
// NotifyPipe.cpp
#include "NotifyPipe.h"
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
NotifyPipe::NotifyPipe()
{
int pipefd[2];
int ret = pipe(pipefd);
assert(ret == 0); // For real usage put proper check here
m_receiveFd = pipefd[0];
m_sendFd = pipefd[1];
fcntl(m_sendFd,F_SETFL,O_NONBLOCK);
}
NotifyPipe::~NotifyPipe()
{
close(m_sendFd);
close(m_receiveFd);
}
int NotifyPipe::receiverFd()
{
return m_receiveFd;
}
void NotifyPipe::notify()
{
write(m_sendFd,"1",1);
}
然后select使用receiverFd(),并使用通知终止notify()。
TA贡献1804条经验 获得超7个赞
使用shutdown()
调用关闭套接字。这将唤醒所有阻塞的线程,同时保持文件描述符有效。
close()
在描述符上,另一个线程B使用具有内在的危险:另一个线程C可能会打开一个新的文件描述符,然后线程B将使用该文件描述符而不是已关闭的文件描述符。dup2()
一/dev/null
到就避免了这个问题,但没有醒来阻塞的线程可靠。
请注意,shutdown()
仅适用于套接字-对于其他类型的描述符,您可能需要select + pipe-to-self或cancel方法。
TA贡献1834条经验 获得超8个赞
如果pthread实现无法正确实现取消,则pthread_cancel取消被accept()阻塞的线程是有风险的,也就是说,如果线程创建了一个套接字,则在返回代码之前,将为其调用pthread_cancel(),该线程为取消,并且新创建的套接字泄漏。尽管FreeBSD 9.0和更高版本没有这种竞争状况问题,但是您应该首先检查操作系统。
- 3 回答
- 0 关注
- 662 浏览
添加回答
举报