[英]Force blocking syscall of other thread to return and set errno to EINTR
please view the following example source code:请查看以下示例源代码:
void tfunc()
{
// Some blocking syscall that sets errno
if (errno == EINTR)
{
std::cout << "cleanup" << std::endl;
return;
}
// Do some other stuff
}
int main(int argc, char *argv[])
{
std::thread t(tfunc);
sleep(10);
return 0;
}
Is it possible, from another thread, to have the syscall, for example accept()
return and set errno
to EINTR
?是否有可能从另一个线程让系统调用,例如
accept()
返回并将errno
为EINTR
? If yes, how?如果是,如何?
I suggest you use:我建议你使用:
poll()
(or select()
or epoll()
) poll()
(或select()
或epoll()
) Before you spawn your thread you setup a pipe which will carry an "interrupt message".在你生成你的线程之前,你设置一个 pipe 它将携带一个“中断消息”。 In your thread
tfunc
you setup poll
such that it waits on both the file descriptor (socket) you want to work on and the read end of the pipe.在您的线程
tfunc
中,您设置poll
以便它等待您要处理的文件描述符(套接字)和pipe 的读取端。
If you want to interrupt that you simply write an "interrupt message" to the write end of the pipe;如果要中断,只需将“中断消息”写入 pipe 的写入端; and in the thread check on return of
poll
whether the pipe has data to read.并在
poll
返回的线程中检查 pipe 是否有数据要读取。
Small demo, no error handling, no handling of signals, just to visualize what I mean:小演示,没有错误处理,没有信号处理,只是为了形象化我的意思:
#include <cassert>
#include <iostream>
#include <thread>
#include <poll.h>
#include <unistd.h>
int fd[2];
void the_blocking_thread(void)
{
pollfd pollfds[2];
pollfds[0].fd = fd[0];
pollfds[0].events = POLLIN;
pollfds[1].fd = -99; // add here your socket / fd
pollfds[1].events = POLLIN; // or whatever you need
std::cout << "waiting for \"interrupt message\" or real work on fd" << std::endl;
int ret = poll(pollfds, 2, -1);
assert(ret > 0);
if (pollfds[0].revents != 0) {
std::cout << "cleanup" << std::endl;
return;
}
// Non blocking call on your fd
// Some other stuff
}
int main() {
int ret = pipe(fd);
assert(ret == 0);
std::cout << "Starting thread" << std::endl;
std::thread t(the_blocking_thread);
std::chrono::seconds timespan(1); // or whatever
std::this_thread::sleep_for(timespan);
std::cout << "Sending \"interrupt\" message" << std::endl;
char dummy = 42;
ret = write (fd[1], &dummy, 1);
assert(ret == 1);
t.join();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.