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;
}
First never use SIGCONT
or another signal like this for custom usage. Prefer using SIGUSR1
and SIGUSR2
. SIGCONT
has some special semantic.
Now even if you change CONT
to, say, USR1
, the way you use pause()
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);
or printf("%c\n",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("%c\n",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;
}