强制其他线程的阻塞系统调用返回并将errno设置为EINTR



请查看以下示例源代码:

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;
}

是否可以从另一个线程让系统调用(例如accept()(返回并将errno设置为EINTR?如果是,如何?

我建议您使用:

  • 非阻塞操作
  • poll()(或select()epoll()(
  • 管子

在生成线程之前,您设置了一个管道,该管道将携带一个";中断消息";。在线程tfunc中,设置poll,使其同时等待要处理的文件描述符(套接字(和管道的读取端

如果你想打断,你只需写一个";中断消息";到管道的写入端;以及在CCD_ 9返回时的线程检查中。

小演示,没有错误处理,没有信号处理,只是为了可视化我的意思:

#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();
}

(实时(

最新更新