簡體   English   中英

強制阻止其他線程的系統調用返回並將 errno 設置為 EINTR

[英]Force blocking syscall of other thread to return and set errno to 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()返回並將errnoEINTR 如果是,如何?

我建議你使用:

  • 非阻塞操作
  • poll() (或select()epoll()
  • 一個 pipe

在你生成你的線程之前,你設置一個 pipe 它將攜帶一個“中斷消息”。 在您的線程tfunc中,您設置poll以便它等待您要處理的文件描述符(套接字)pipe 的讀取端。

如果要中斷,只需將“中斷消息”寫入 pipe 的寫入端; 並在poll返回的線程中檢查 pipe 是否有數據要讀取。

小演示,沒有錯誤處理,沒有信號處理,只是為了形象化我的意思:

#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM