1

我正在尝试开发一个程序来限制函数的执行。在下面的代码中,我有一个名为的函数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");
}
4

1 回答 1

3

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

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

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

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

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

于 2010-09-01T21:14:22.863 回答