我正在进行一项使用蒙特卡罗模拟的任务,以确定将产生多少随机地址访问。故障直到ULONG_MAX尝试次数。我们被指示创建信号处理程序来处理这些信号SIGSEGV,SIGIINT,SIGTSTP,SIGALRM,SIGUSR1和SIGUSR2。
我有几个关于SIGSEGV,SIGUSR1和SIGUSR2的问题。
对于SIGSEGV,我查看了sigsetjmp和siglongjmp的手册页,但我很困惑这些函数的参数应该做什么。
对于USR信号,方向是: SIGUSR1 / SIGUSR2 - 每当执行10次评估时, 然后,当前估计的准确度增加一位精度。例如, 在进行了100次评估之后,已知答案在1/100或两位数内 精度,并且当执行了1000时,那么答案就在内部已知 1/1000,或3位精度。这个进展将传达给父母(shell) 你写的)以下列方式:
每次评估的次数超过10次,孩子都应该使用 kill()命令将SIGUSR1信号发送给父级。 (最简单的方法 这是设置一个“报告”变量,最初为10,每次都是数量 评估与报告变量匹配发送信号并将报告变量相乘 由10.)
父级现在需要一个信号处理程序来捕获SIGUSR1,并增加一个计数器 每次它到来。如果计数器超过了命令行上设置的限制 shell已启动,然后父进程使用kill()系统调用发送SIGUSR2 向孩子发出信号。 (计数器需要在之前的某个时间重置为零 启动下一个孩子。 )
孩子现在需要一个信号处理程序来捕获SIGUSR2。答案应该是 与control-C相同,实际上可能是同一个处理程序。
所以,话虽如此,我完全混淆了如何制作/放置这两个USR信号的位置。 有人可以帮我从这里出去吗。我非常感谢。这是我一直在研究的代码(减去shell,我确定它工作正常。已经过测试)。
#include <iostream>
#include <cstdlib> /* srand, rand */
#include <time.h> /* time */
#include <limits.h>
#include <setjmp.h>
#include <signal.h>
using namespace std;
#define MAXARGS 512
/* Monte Carlo Simulator */
unsigned long int seg_fault = 0; // count for generated segfaults due to attempts
unsigned long int attempts = 0; // count for evaluations attempted
// functions
void handler_seg (int sig);
void handler_int (int sig);
void handler_tstp (int sig);
void handler_alrm (int arg);
void handler_usr1 (int sig);
void handler_usr2 (int sig);
/* Takes floating point command line argument as max seconds to run before stopping.
If +, call alarm before starting the for loop*/
/*Generated by CTRL-C, signal handler simply reports the final results and exits */
void handler_int (int sig)
{
cout << "SIG_INT called" << endl;
cout << "Total number of SEG_FAULTS: " << seg_fault << endl;
cout << "Total number of evaluations: " << attempts << endl;
double percent = seg_fault/attempts;
cout << "The percentage of seg_fault attempts: " << percent << endl;
exit ((int)percent);
}
/*Generated by CTRL-Z, reports the current results without stopping program, this
handler doesnt exit, and returns when complete */
void handler_tstp (int sig)
{
cout << "SIG_TSTP called" << endl;
cout << "Total number of SEG_FAULTS: " << seg_fault << endl;
cout << "Total number of evaluations: " << attempts << endl;
double percent = seg_fault/attempts;
cout << "The percentage of seg_fault attempts: " << percent << endl;
return; // can go right back to what you were doing because no errors to report
}
void handler_seg (int sig)
{
seg_fault++;
attempts++;
// return of the handler if eval counter hasnt reached the limit ulong_max
if (attempts != ULONG_MAX)
siglongjmp(); // fixes the error of seg_fault infinite loop
else
{
cout << "SIG_INT called" << endl;
cout << "Total number of SEG_FAULTS: " << seg_fault << endl;
cout << "Total number of evaluations: " << attempts << endl;
double percent = seg_fault/attempts;
cout << "The percentage of seg_fault attempts: " << percent << endl;
exit ((int)percent);
}
}
int main (int argc, char* argv[], char **envp)
{
srand (time(NULL));
int count = 0;
char *cargs[MAXARGS];
int alrmReq = 0;
// need to parse any command line arguments that are present
for (int i=0 ; i<argc ; i++)
{
cout << argv[i] << endl;
cargs[i] = argv[i];
if (i == argc-1)
alrmReq = atoi(argv[i]); // set the alarm value
}
// Set up signal handlers to catch and respond to certain signals
signal (SIGSEGV, handler_seg);
// for loop to generate and test random addresses using global eval
// counter for the loop counter
if (alrmReq > 0)
{
alarm (alrmReq);
signal (SIGALRM, handler_alrm);
}
int* address_ptr = NULL; // initialization only occurs for the first run in a loop
int temp = 0;
int report = 10;
for (attempts=0; attempts<100 ; attempts++) // ULONG_MAX
{
sigsetjmp(); // remembers the context at the beginnging of the loop
attempts++;
address_ptr = (int*)rand(); // possibly not all the mem locations
// attempt to read from possible seg_fault location
temp = *address_ptr; // for seg fault returns back to redo instruction that caused the fault
// check if attempts is a power of 10
if (attempts == report)
{
//child use the kill command to send SIGUSR1 signal to parent
signal (SIGUSR1, handler_usr1);
report = report*10;
}
}
// successfully completed the for loop
cout << "Successfully completed the for loop" << endl;
cout << "Total number of SEG_FAULTS: " << seg_fault << endl;
cout << "Total number of evaluations: " << attempts << endl;
double percent = seg_fault/attempts;
cout << "The percentage of seg_fault attempts: " << percent << endl;
exit ((int)percent);
}