C POSIX子级根据文件内容发送信号,父级将接收到的信号与文件匹配
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C POSIX子级根据文件内容发送信号,父级将接收到的信号与文件匹配相关的知识,希望对你有一定的参考价值。
[不幸的是,我没有C POSIX的经验,我必须编写一个程序,该程序将接受一个参数(包含二进制数的文件名)并解析该文件。文件中指示的每一位意味着应创建一个孩子(每一位专用于一个孩子)。位的值(0或1)决定应将哪些信号发送到父级(0-SIGUSR1,1-SIGUSR2)。子进程应选择一个随机间隔(10-200ms),并向父进程发送适当的信号。
父母应接收信号,并在每次收到新信号时打印接收到的最后5位。
最后一步是匹配过程-父级检查接收到的信号(分配给SIGUSR1或SIGUSR2的位),如果匹配,则打印SUCCESS。如果没有匹配项(每当发送错误位-与文件进行比较),父级将从头开始匹配。
到目前为止我所做的:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <signal.h>
char * str; // the array consisting of bits from the file
char * received; //array of the parent receiving the signals
int count = 0;
//Error macro
#define ERR(source) (fprintf(stderr,"%s:%d
",__FILE__,__LINE__),
perror(source),kill(0,SIGKILL),
exit(EXIT_FAILURE))
void sethandler( void (*f)(int), int sigNo)
{
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
act.sa_handler = f;
if (-1==sigaction(sigNo, &act, NULL)) ERR("sigaction");
}
//Reading file char by char and returning allocated char array
char *readFile(char *fileName)
{
FILE *file = fopen(fileName, "r");
char *code;
size_t n = 0;
int c;
if (file == NULL) return NULL; //could not open file
fseek(file, 0, SEEK_END);
long f_size = ftell(file);
fseek(file, 0, SEEK_SET);
code = malloc(f_size);
received = malloc(f_size);
while ((c = fgetc(file)) != EOF) {
code[n++] = (char)c;
}
code[n] = ' ';
return code;
}
// Append the character to the received array
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = ' ';
}
// SIGUSR1 handler. I tried to implement simple counter to check if the parent is receiving the signals, then proceed to printing last 5 bits received. Unfortunately this part seems to not work at all.
static void sig_handle1(int signum)
{
signal(SIGUSR1, sig_handle1);
count++;
printf("%d
", count);
}
// Handler for SIGUSR2 - same as handler for SIGUSR1
static void sig_handle2(int signum)
{
signal(SIGUSR2, sig_handle2);
count++;
printf("%d
", count);
}
// Child function - set the random interval, wait and then send the appropriate signal to the parent
void child_w(int number_of)
{
srand(time(NULL)*getpid());
int time = rand()%100 + 10;
struct timespec time_wait = {time/1000, 0};
nanosleep(&time_wait, NULL);
if(str[number_of] == '0')
{
if (kill(getppid(), SIGUSR1)==0) printf("[SIGUSR1] sent
");
else
{
printf("ERROR kill.
");
exit(EXIT_FAILURE);
}
}
if(str[number_of] == '1')
{
if (kill(getppid(), SIGUSR2) == 0) printf("[SIGUSR2] sent
");
else
{
printf("ERROR kill.
");
exit(EXIT_FAILURE);
}
}
}
// Function which will create children (number of children = number of bits in the file)
void create_children(int n)
{
pid_t s;
int j = n;
while(j-->0)
{
if((s=fork())<0) ERR("Fork ERROR");
if(!s) {
printf("Child %d started ", j);
printf("with bit: %c
", str[j]);
child_w(j);
//if(j==1) kill(getppid(), SIGUSR2);
exit(EXIT_SUCCESS);
}
}
}
// Parent function to check the received signals
void parent_w()
{
while(1)
{
signal(SIGUSR1, sig_handle1);
}
}
int main(int argc, char ** argv)
{
char filename[250];
if(argc!=2)
{
printf("Provide one parameter - filename.
");
return EXIT_FAILURE;
}
strcpy(filename, argv[1]);
str = readFile(filename);
printf("FILE: ");
for(int i=0; i<sizeof(str); ++i)
{
printf("%c ", str[i]);
}
printf("
");
sethandler(SIG_IGN,SIGUSR1);
sethandler(SIG_IGN,SIGUSR2);
create_children(sizeof(str)-1);
parent_w();
free(str);
free(received);
return EXIT_SUCCESS;
}
我得到的输出:
FILE: 1 0 0 1 1 0 1
Child 6 started with bit: 1
[SIGUSR2] sent
Child 5 started with bit: 0
[SIGUSR1] sent
Child 4 started with bit: 1
[SIGUSR2] sent
Child 3 started with bit: 1
[SIGUSR2] sent
Child 2 started with bit: 0
[SIGUSR1] sent
Child 1 started with bit: 0
[SIGUSR1] sent
1
Child 0 started with bit: 1
[SIGUSR2] sent
文件已正确解析。创建了适当数量的子代,似乎他们向父代发送了适当的信号。
问题在于接收信号的父级处理(似乎只有count = 1显示在中间的某处)。显然,如果没有父母的适当信号处理,我将无法尝试执行最后一步-尽管如此,我真的不知道如何在不编写过于复杂的内容的情况下制作此类东西。
任何建议/帮助将不胜感激。
答案
首先,好的代码。
第二:
- 手册页是您的朋友。 man signal
signal()
registers信号处理程序。因此,在signal(SIGUSR1, some_function)
之后,将在接收到信号后执行功能some_function
。- 从信号处理程序调用Removoe
signal()
(为什么要从处理程序内部重新注册相同的处理程序?它已经是此信号的处理程序。) - 从父级的循环中删除
signal()
调用。只需注册一次功能就可以了。 - 您的
sethandler
功能与signal
相同。
经过一些修复:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <signal.h>
char * str; // the array consisting of bits from the file
char * received; //array of the parent receiving the signals
int count = 0;
//Error macro
#define ERR(source) (fprintf(stderr,"%s:%d
",__FILE__,__LINE__),
perror(source),exit(EXIT_FAILURE))
//Reading file char by char and returning allocated char array
char *readFile(char *fileName)
{
FILE *file = fopen(fileName, "r");
char *code;
size_t n = 0;
int c;
if (file == NULL) return NULL; //could not open file
fseek(file, 0, SEEK_END);
long f_size = ftell(file);
fseek(file, 0, SEEK_SET);
code = malloc(f_size);
received = malloc(f_size);
while ((c = fgetc(file)) != EOF) {
code[n++] = (char)c;
}
code[n] = ' ';
return code;
}
// Append the character to the received array
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = ' ';
}
// SIGUSR1 handler. I tried to implement simple counter to check if the parent is receiving the signals, then proceed to printing last 5 bits received. Unfortunately this part seems to not work at all.
static void sig_handle1(int signum) {
count++;
printf("%s %d
", __func__, count);
}
// Handler for SIGUSR2 - same as handler for SIGUSR1
static void sig_handle2(int signum) {
count++;
printf("%s %d
", __func__, count);
}
// Child function - set the random interval, wait and then send the appropriate signal to the parent
void child_w(int number_of)
{
srand(time(NULL)*getpid());
int time = rand()%100 + 10;
struct timespec time_wait = {time/1000, 0};
nanosleep(&time_wait, NULL);
if(str[number_of] == '0')
{
if (kill(getppid(), SIGUSR1)==0) printf("[SIGUSR1] sent
");
else
{
printf("ERROR kill.
");
exit(EXIT_FAILURE);
}
}
if(str[number_of] == '1')
{
if (kill(getppid(), SIGUSR2) == 0) printf("[SIGUSR2] sent
");
else
{
printf("ERROR kill.
");
exit(EXIT_FAILURE);
}
}
}
// Function which will create children (number of children = number of bits in the file)
void create_children(int n)
{
pid_t s;
int j = n;
while(j-->0)
{
if((s=fork())<0) ERR("Fork ERROR");
if(!s) {
printf("Child %d started ", j);
printf("with bit: %c
", str[j]);
child_w(j);
//if(j==1) kill(getppid(), SIGUSR2);
exit(EXIT_SUCCESS);
}
}
}
// Parent function to check the received signals
void parent_w()
{
signal(SIGUSR1, sig_handle1);
signal(SIGUSR2, sig_handle2);
while(1)
{
pause();
}
}
int main(int argc, char ** argv)
{
char filename[250];
if(argc!=2)
{
printf("Provide one parameter - filename.
");
return EXIT_FAILURE;
}
strcpy(filename, argv[1]);
str = readFile(filename);
printf("FILE: ");
for(int i=0; i<sizeof(str); ++i)
{
printf("%c ", str[i]);
}
printf("
");
create_children(sizeof(str)-1);
parent_w();
free(str);
free(received);
return EXIT_SUCCESS;
}
以上是关于C POSIX子级根据文件内容发送信号,父级将接收到的信号与文件匹配的主要内容,如果未能解决你的问题,请参考以下文章