Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <time.h>
- #define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
- perror(source),kill(0,SIGKILL),\
- exit(EXIT_FAILURE))
- volatile sig_atomic_t last_signal = 0;
- volatile sig_atomic_t sig_count = 0;
- 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");
- }
- void sig_handler(int sig) {
- last_signal = sig;
- sig_count++;
- printf("[%d] received %d SIGUSR1\n", getpid(), sig_count);
- }
- ssize_t bulk_write(int fd, char *buf, size_t count){
- ssize_t c;
- ssize_t len=0;
- do{
- c=TEMP_FAILURE_RETRY(write(fd,buf,count));
- if(c<0) return c;
- buf+=c;
- len+=c;
- count-=c;
- }while(count>0);
- return len ;
- }
- void parent_work() {
- struct timespec t = {0, 10*1000000};
- sethandler(SIG_IGN, SIGUSR1);
- for (int i=0; i<100; i++){
- nanosleep(&t,NULL);
- if (kill(0, SIGUSR1)<0)ERR("kill");
- }
- printf("[PARENT] Terminates \n");
- }
- void child_work(int i) {
- int com=0;
- struct timespec t = {2, 0};
- struct timespec tt;
- /*for (int i=0; i<100; i++){
- sigsuspend(&oldmask);
- com++;
- printf("[%d] received %d SIGUSR2\n", getpid(), com);
- }*/
- //sethandler(sig_handler,SIGUSR1);
- sleep(1);
- int out;
- ssize_t count;
- srand(time(NULL)*getpid());
- int s=10+rand()%(100-10+1);
- printf("n=%d, s=%d\n", i, s);
- char *buf=malloc(s*1024);
- if(!buf) ERR("malloc");
- memset(buf, i+'0', s*1024);
- char name[15];
- sprintf(name, "%d.TXT", getpid());
- //printf("%s", name);
- if((out=TEMP_FAILURE_RETRY(open(name,O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,0777)))<0)ERR("open");
- while(0!=nanosleep(&t,NULL))
- {
- while(0<sig_count-com)
- {
- if((count=bulk_write(out,buf,s))<0) ERR("write");
- com++;
- }
- }
- if(TEMP_FAILURE_RETRY(close(out)))ERR("close");
- //printf("[%d] received %d SIGUSR1\n", getpid(), com);
- }
- void create_children(int n, char** arg) {
- pid_t s;
- for (int i=1;i<n;i++) {
- if((s=fork())<0) ERR("Fork:");
- if(!s) {
- sethandler(sig_handler,SIGUSR1);
- child_work(atoi(arg[i]));
- exit(EXIT_SUCCESS);
- }
- }
- }
- void usage(char *name){
- fprintf(stderr,"USAGE: %s 0<n\n",name);
- exit(EXIT_FAILURE);
- }
- int main(int argc, char** argv) {
- int n=argc-1;
- if(argc<2) usage(argv[0]);
- //sethandler(sig_handler,SIGUSR1);
- create_children(argc, argv);
- parent_work();
- while(n>0){
- sleep(3);
- pid_t pid;
- for(;;){
- pid=waitpid(0, NULL, WNOHANG);
- if(pid>0) n--;
- if(0==pid) break;
- if(0>=pid) {
- if(ECHILD==errno) break;
- ERR("waitpid:");
- }
- }
- printf("PARENT: %d processes remain\n",n);
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement