c - 如何为具有安全区域的功能设置时间限制

标签 c signals preemption

我正在尝试开发一个程序来限制函数执行的时间。在下面的代码中,我有一个名为 Inc 的函数,它执行大量迭代(由无限循环模拟)。每次迭代的第一部分很长,接下来的第二部分应该会很快。

我不介意在代码的第一部分抢占执行,但我想在第二部分执行写操作时避免警报响起。

我的第一个想法是在进入“安全区域”之前关闭警报以节省剩余时间。然后退出后,我会用保存的时间设置闹钟。我不知道如何实现这个。有人可以帮我吗?也欢迎使用其他方法。

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_t thread;
FILE *fout;

void *Inc(void *param){

    int i;
    long long int x = 0;

    fout = fopen("file.txt", "w");

    /* Large number of iterations */
    while(1){

        int k = 0;
        for(i=0; i<5000000; i++)
            k += (rand())%3;
        x += k;

        printf("%lld\n", x);
        /* Enter Safe Region */
        fprintf(fout, "%lld\n", x);
        /* Exit Safe Region */
    }   
}

void Finish(int param){
    pthread_cancel(thread);
    fclose(fout);
}

main (){

    pthread_attr_t attr;
    void *status;

    signal(SIGALRM, Finish);
    alarm(10);

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_create(&thread, &attr, Inc, NULL);
    pthread_attr_destroy(&attr);
    pthread_join(thread, &status);

    printf("Program Finished\n");
}

最佳答案

显而易见的事情是在调用 pthread_cancel 之前获取锁,并在您的“安全区域”中持有相同的锁。

不幸的是,您不能在信号处理程序中等待互斥量或信号量。但是警报信号并不是 10 秒后做某事的唯一方法 - 您可以让主线程休眠 10 秒,然后醒来,获取锁,取消工作线程,然后加入它。

当然这意味着即使工作线程在 5 秒后完成,主线程也会休眠 10 秒。因此,不是休眠,而是让主线程在信号量上执行 10 秒定时等待,工作线程在完成时发布。

就像 sleep 一样,定时等待可以由于信号提前完成,所以一定要在 EINTR 上重试定时等待。您的重要案例是 EINTR(再次等待)、成功(加入工作线程 - 无需取消,因为它已发布信号量)、ETIMEDOUT(获取锁、取消、加入)以及其他错误(如果您愿意)。不过,没有为 sem_timedwait 列出会影响您的其他错误。

另一个想法是在您的“安全区域”中阻止 SIGALRM,这会更简单,除了 (a) 我永远不记得如何在禁用信号的情况下安全地执行 I/O,以及 (b) 您的工作线程可能是与信号处理程序“同时”运行(实际上是同时的,或者显然是由于抢占),这意味着可以获取信号,然后您的工作人员禁用信号并进入临界区,然后信号处理程序将其取消。如果没有人回答谁能真正记住细节,这里有一些 information on blocking signals .

关于c - 如何为具有安全区域的功能设置时间限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3622015/

相关文章:

linux - mq_send 是原子的吗?

java - 无法在从 Java 启动的子进程中为 SIGQUIT 设置信号处理程序

kernel - 为什么linux在内核代码持有自旋锁后禁用内核抢占?

algorithm - 创建基于优先级的循环算法

C: 抑制来自二进制的系统调用

c - 如何检测 TCP 套接字断开连接(使用 C Berkeley 套接字)

c - 使用 C 在 OS X 上确定进程是否暂停(使用 SIGSTOP)

linux - "linux kernel is preemptive"是什么意思?

c++ - 如何左移一个特定位?

c - Ubuntu 中 timeval 结构返回的时间是错误的