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