Write a program that can display a text string (consisting only of the 26 alphabets and spaces). The program should fork 27 worker processes. Each worker process runs an infinite loop in which it waits for a signal from the controller (i.e., parent), sleeps for 1 sec, prints its pre-defined character, signals the controller, then blocks again. The controller reads a string from the keyboard, then signals the workers in the correct order to get the string displayed The following is my code, but I am not getting output, it isn’t printing anything.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <signal.h> #include <sys/types.h> #include <string.h> int main() { /*...declarations and stuff....*/ scanf("%s",inputString); length=strlen(inputString); for (i=0;i<27;i++) { pid[i]=fork(); if (pid[i]==0) { /*...Declare my character...*/ while (1) { pause(); sleep(1); printf("%c",myChar); kill(ppid,SIGCONT); } return 0; } } for (i=0;i<length;i++) { int temp=inputString[i]; if (temp==32) { kill(pid[0],SIGCONT); } else { kill(pid[temp-96],SIGCONT); } pause(); } for(i=0;i<27;i++) kill(pid[i],SIGTERM); return 0; }
Advertisement
Answer
First never use
SIGCONT
or another signal like this for custom usage. Prefer usingSIGUSR1
andSIGUSR2
.SIGCONT
has some special semantic.Now even if you change
CONT
to, say,USR1
, the way you usepause()
is a problem. After the child process been awaked, it will be killed because you didn’t catched signals. Manual says:
pause()
causes the calling process (or thread) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching function.
Children will never signal the right process as you did not set
ppid
to a correct value.You will never experienced printings correctly because writes are buffered and there is no flushing. Either use
printf("%c",myChar); fflush(stdout);
orprintf("%cn",myChar);
That will lead to something like:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <signal.h> #include <sys/types.h> #include <string.h> void handler(int sig) { } int main() { pid_t ppid; int length; char inputString[256]; pid_t pid[256]; int i; char myChar; scanf("%s",inputString); length=strlen(inputString); struct sigaction action; sigemptyset(&(action.sa_mask)); action.sa_flags = 0; action.sa_handler = handler; sigaction(SIGUSR1,&action,NULL); ppid = getpid(); for (i=0;i<27;i++) { pid[i]=fork(); if (pid[i]==0) { myChar='a'+i; while (1) { pause(); sleep(1); printf("%cn",myChar); kill(ppid,SIGUSR1); } return 0; } } for (i=0;i<length;i++) { int temp=inputString[i]; if (temp==32) { kill(pid[0],SIGUSR1); } else { kill(pid[temp-'a'],SIGUSR1); } pause(); } for(i=0;i<27;i++) kill(pid[i],SIGTERM); return 0; }
- There is little much more thing to say, like why looping over 27?, etc, but these are actually minor problems (this not to say not to correct them later).