c++ - 操作系统回调如何工作

标签 c++ c unix posix

跟进问题: This question

如链接问题中所述,我们有一个 API,它使用轮询 select() 的事件外观来处理用户定义的回调。

我有一个像这样使用它的类:

class example{
 public:
    example(){
        Timer* theTimer1 =  Timer::Event::create(timeInterval,&example::FunctionName);
        Timer* theTimer2 =  Timer::Event::create(timeInterval,&example::FunctionName);
        start();
       cout<<pthread_self()<<endl;
    }
  private:
     void start(){
        while(true){
           if(condition)
              FunctionName();
           sleep(1);
        }
     }
     void FunctionName(){
         cout<<pthread_self()<<endl;
         //Do stuff
     }
};

这背后的想法是,您希望在条件为真或计时器启动时调用 FunctionName。不是一个复杂的概念。我想知道的是,是否会同时在 start() 函数和回调中调用 FunctionName?这可能会导致一些内存损坏,因为它们访问了一 block 非线程安全的共享内存。

我的测试告诉我它们确实在不同的线程中运行(只有当我使用事件时才会损坏),即使:cout<<pthread_self()<<endl;说他们有相同的线程ID。

有人可以向我解释这些回调是如何 fork 的吗?他们执行什么命令?他们在什么线程中运行?我假设它们在执行 select() 的线程中运行,但是它们什么时候获得相同的线程 ID?

最佳答案

真正的答案将取决于 Timer 的实现,但如果您从同一线程获得回调,则很可能使用 signalsposix timers .无论哪种方式,select()根本不参与。

对于信号和 posix 计时器,您几乎无法从信号处理程序中安全地执行操作。只有某些特定的信号安全调用,例如 read()write() (NOT fread() 和 fwrite(),甚至 new 和 cout)被允许使用。通常会做的是 write() 到 pipeeventfd ,然后在另一个线程或运行 select() 的主事件循环中,注意此通知并处理它。这使您能够以安全的方式处理信号。

关于c++ - 操作系统回调如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1233963/

相关文章:

c - 使用宏与其扩展之间的区别

c - 如何在 openCL 中将 char* 类型转换为 int*

unix - 在shell脚本中确定文件的年龄

linux - 如何使用 paste(1) 排列列?或者如何在 shell 中制作对齐的表格合并线?

C通过分隔符将字符串拆分为token并保存为变量

c - 在 C 中删除原始文件的符号链接(symbolic link)

c++ - 如何实现decltype功能-C++ 11之前的编译时间

c# - Windows 中文件的全局唯一 ID

c++ - C++中的静态变量构造

c++ - 使用 C++ 拆分 "[General Setting]"格式的节字符串