c/c++语言开发共享在C中等待中断的有效方法

我在树莓派上使用WiringPi。 有了它,我分配了一个稍后调用的中断函数。 我不确定在等待中断被呼叫时该怎么做。

示例使用(自旋锁?) for (;;)例如

 int main() { // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { // really? } return 0; } 

而且我注意到sleep也有效。 无论睡眠如何,都会调用中断

 int main() { // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { sleep(1000000); } return 0; } 

使用最少的资源保持程序运行的最佳做法是什么(比如这是用于背景恶魔)?

来自其他语言,我原以为for(;;)会占用资源。 我想知道该怎么做或指示做什么(线程等)。

    我最近不得不这样做。 我的理论是KISS 。 写入sleep是为了根据定义使用最少的资源 – 使用它意味着我不必关心线程。

    原始Raspberry Pi B上简单,可读且无可测量的性能:

     int main() { // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { sleep(UINT_MAX); } return 0; } 

    注意使用UINT_MAX来最小化for循环调用的次数 – 这假设是无符号的32位定时器延迟,这是WiringPi使用的。

    WiringPi设置一个单独的线程并从该线程调用您的isr函数。

    然后,您可以使用pthread条件变量来阻止另一个线程,在这种情况下为main(),并让isr函数在发生中断时将其唤醒。

     #include  pthread_cond_t isr_cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t isr_mtx = PTHREAD_MUTEX_INITIALIZER; unsigned int isr_count = 0; void myInterrupt(void) { pthread_mutex_lock(&isr_mtx); isr_count++; pthread_cond_signal(&isr_cond); pthread_mutex_unlock(&isr_mtx); } int main() { // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { pthread_mutex_lock(&isr_mtx); while (isr_count == 0) { pthread_cond_wait(&isr_cond, &isr_mtx); } //add logic here to handle the ISR, isr_count //tells you how many ISRs occured. //heavy work should be moved outside the mutex. isr_count = 0; pthread_mutex_unlock(&isr_mtx); } return 0; } 

    您需要使用-pthread标志编译和链接代码。

    您也可以使用信号量 。 sem_post() 必须是异步信号安全的 :

     #include  static sem_t staticSem; void myInterupt( void ) { sem_post( &staticSem ); } int main() { sem_init( &staticSem, 0, 0 ); // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { sem_wait( &staticSem ); ... } return 0; } 

    不包括从sem_wait()检查和处理潜在的虚假sem_wait()错误。

    这取决于您是否需要在用户级别进行通知。 在某些情况下,然后:

    1)’因为我处于中断状态,所以我根本不需要任何通知’。 很好,在main()中使用长Sleep()循环,或Sleep(INFINITE)(如果可用)等待,或等待一些从未发出信号的同步对象,或循环某些’设置低功耗状态’或’HALT’指令。 这将从用户状态中删除执行需求,并让处理器等待中断。

    2)’我需要在用户状态下通知,但我不关心延迟’。 好的,从中断状态设置一些primefacesint或布尔值,并从需要注意中断可能发生的main()或线程轮询它。 这样的轮询可能会浪费并且响应缓慢,但如果您不需要关心您的应用程序,那么很好:)

    3)’我需要在用户状态下尽快通知’。 实现这种信令的“经典”方式是让信号量上的处理程序线程等待,从中断处理程序发出信号,并在中断处理程序结束后“指示”操作系统必须执行重新调度。 所以使等待线程准备好/正在运行。 其他信号机制,例如。 事件/ condvars,也可以安全地从中断状态发出信号,但是您应该查看您的操作系统文档。

    我该怎么办? 你不能和/或不能在可能试图阻止的中断状态下调用任何东西。 这是灾难性的,你的操作系统可能会摔倒:(

    我特别不确定WiringPi,但是当完成任务时,如何使用等待由中断处理程序引导的signalpthread_cond_t

    这是一个参考。

    我会(而且,当嵌入编码时)而是使用自旋锁while(1) ; 。 它很简单,表达意图 – 永远不会超越这一点。

    睡眠不仅具有过期时间,这可能不会立即成为问题,而是在多年后成为问题。 它还必须执行一些计算以实际计算时间。

    这是sleep(0xFFFFFFFF);之间的比较sleep(0xFFFFFFFF); 在英特尔酷睿i3-4330TE上:

      .file "test.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $-1, %edi movl $0, %eax call sleep movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Debian 4.9.2-10) 4.9.2" .section .note.GNU-stack,"",@progbits 

    while(1); 做法:

      .file "test.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 .L2: jmp .L2 .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Debian 4.9.2-10) 4.9.2" .section .note.GNU-stack,"",@progbits 

    如果不追踪时间,那么就会减少工作量。 我不确定linux调度程序是否可以在ISR到达之前识别此模式。


    说到这里,“使用最少的资源保持程序运行”的正确方法是研究处理器提供的睡眠模式(第2-14页或第36页) 。

      以上就是c/c++开发分享在C中等待中断的有效方法相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/541955.html

      (0)
      上一篇 2021年1月5日
      下一篇 2021年1月5日

      精彩推荐