I am working on an assignment where we need to use semaphores in order to make the second print of the parent process wait until child executes first. It is first time using semaphores and I certainly understood how they work, however I think I have a problem with the initialising of sem_open().
By following this:
sem_t *sem_open(const char *name, int oflag);
I have created this:
sem_t *sem = sem_open("MYSEM", O_CREAT , 2);
However, when executing my sem_wait are ignored.This is my whole program:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
/* void ChildProcess(void) ChildProcess prototype */
/* void ParentProcess(void) ParentProcess prototype */
int main(int argc, char ** argv){
int pid;
pid = fork();
sem_t *sem = sem_open("MYSEM", O_CREAT , 2);
if (pid<0)
{
printf("Cannot create a child process");
exit(EXIT_FAILURE);
}
else if (pid==0)
{
printf("I am the child process. \n");
printf("The child process is done. \n");
sem_post(sem);
exit(EXIT_SUCCESS);
}
else
{
printf("I am the parent process. \n");
sem_wait(sem);
printf("The parent process is done. \n");
}
sem_destroy(sem);
exit (EXIT_SUCCESS);
}
and what is printing is:
I am the parent process.
The parent process is done.
I am the child process.
The child process is done.
and what should print is this:
I am the parent process.
I am the child process.
The child process is done.
The parent process is done.
in the parent : you create a semaphore, print a message and then wait for the semaphore.
in the child : you create a semaphore, print 2 messages, close the semaphone and exit.
now the parent can return from the wait.
See http://man7.org/linux/man-pages/man3/sem_wait.3.html for a trivial example
Related
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
static void sigusr(int iSig) //SIGUSER are the user defined signals
{
if (iSig == SIGUSR1)
{
printf("Received SIGUSR1 signal, going to sleep for 2 seconds\n");
sleep(2);
}
}
int main ()
{
int pid;
signal(SIGUSR1, sigusr);
pid = fork();
if (pid > 0) //Parent process created
{
for(int i=0; i<=1000;i++)
{
printf("%d\n",i);
usleep(70);
}
}
else //Child process created
{
sleep(5);
kill(pid,SIGUSR1);
exit(0);
}
}
Create 2 processes, a parent and a child using fork().
The parent prints the value of ‘i’ from 0 to 1000 and then exits.
Meanwhile the child process sleeps for 5 seconds after it is created,
sends a SIGUSR1 signal to the parent and then exits.
The parent should catch that signal, print on standard output “Received SIGUSR1 signal,
going to sleep for 2 seconds”, sleep for two seconds and then continueprinting the numbers.
But i am unable to continue the process after child process termination.
For me everything works fine if I increase usleep time, without it parent process terminates before child process send signal.
The problem is with kill call, else statement is executed only in child process, so it means that pid value is 0, kill with pid 0 sends signal to whole group, in this case to parent and a child, you should change it to
kill(getppid(), SIGUSR1);
In addition to the #complikator 's answer, you shoudl print and sleep outside the signal handler.
There are remaining questions like "main finishes before the signal is received", but this is really depending on you use case...
would look like this:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
volatile static bool called = false;
static void sigusr(int iSig)
{
called = true;
}
void check_signaled(void) {
if (called) {
called = false;
printf("Received SIGUSR1 signal, going to sleep for 2 seconds\n");
sleep(2);
}
}
int main(void)
{
int pid;
pid = fork();
if (pid > 0) //Parent process created
{
signal(SIGUSR1, sigusr);
for(int i=0; i<=1000;i++)
{
check_signaled(); /* if signal come while iterating */
printf("%d\n",i);
usleep(70);
}
wait(NULL); /* wait child completion */
check_signaled(); /* signal may happen "too late" */
}
else //Child process created
{
sleep(1);
kill(getppid(),SIGUSR1);
}
}
I am trying to call make a thread to another function in a function being ran by a child process. I am starting by calling a child process, which makes another child process, which in turn makes a thread. However, the thread function keeps executing prematurely. What could be the issue?
#define _GNU_SOURCE
#include <sched.h>
#include <pthread.h> // pthread
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>// waitpid
#include <sys/wait.h> //waitpid
#define STACK_Size 1024*1024
void* print(void* ptr)
{
printf("\n4. In thread\n");
char* message;
message = (char*)ptr;
printf("\n5. Message from parent: %s \n\n",message);
}
static int threading(void * ptr)
{
char* message;
message = (char*)ptr;
printf("\n3. In child process 2\n");
pthread_t Tid;
pthread_create(&Tid,NULL,&print,(void*)message);
pthread_join(Tid,NULL);
printf("\n6. Thread done.... exiting child process 2\n\n");
}
static int child(void *ptr)
{
char* message;
message = (char*) ptr;
print("\n2. In child 1");
// creating child process
char* stack_ptr = malloc(STACK_Size);
unsigned long flags =0;
pid_t pid;
pid = clone(threading, stack_ptr+STACK_Size,flags | SIGCHLD,message);
int status;
waitpid(pid,&status,0);
printf("7. Done with child 2\n\n8. Now exiting child process 1\n");
}
int main(int argc, char ** argv)
{
char msg[150];
printf("1. Currently in main program name: %s\n", argv[0]);
sprintf(msg,"The name of the program is (%s), P.S this is parent (pid:%d)",argv[0],getpid());
char* stack_pointer = malloc(STACK_Size);
unsigned long flags =0;
setbuf(stdout,NULL);
if((argc >1) && (strcmp(argv[1],"vm")==0))
{
flags = CLONE_VM;
}
pid_t pid;
pid = clone(child,stack_pointer+STACK_Size,flags | SIGCHLD,msg);
int status;
waitpid(pid,&status,0);
printf("\n9. Done with Parent process\n");
}
Here is the output it's producing:
1. Currently in main program name: ./clone
4. In thread
5. Message from parent:
2. In child 1
3. In child process 2
4. In thread
5. Message from parent: The name of the program is (./clone), P.S this is parent (pid:15159)
6. Thread done.... exiting child process 2
7. Done with child 2
8. Now exiting child process 1
9. Done with Parent process
If what you mean by executing prematurely is the lines containing 4. and 5. being printed before 2., it's because you call your custom print() function to output 2. (print("\n2. In child 1")) which also prints out 4. and 5..
Following is the case.
{
...
pthread_create(thread_id, NULL, thread_fun, NULL);
pthread_join(thread_id, NULL);
...
}
void * thread_fun(void * arg)
{
if(fork())
{
printf("In Parent\n");
pthread_exit(NULL);
}
else
{
printf("In Child\n");
pthread_exit(NULL);
}
}
How to use pthread_join() in such a way that I can wait for both child and parent process in thread?
Put all threads into endless loops and then inspect the whole program state with ps, top, htop or similar tools. You will find that the child process only has a single thread, while the parent process has (at least) two.
Now, concerning your question how to use pthread_join() to wait for the child process, you simply can't, because you can only use it to wait for threads in the same process. You could wait for the child process to terminate (waitpid()).
If the above doesn't answer your question (it's a bit unclear because you want to "wait for both child and parent process", which is where I wonder from which process' context) take a step back instead and describe on a higher level what you're trying to achieve instead. In other words, this could be a so-called "XY Problem". Do a bit of research on that term, it's a good thing to learn and understand in any case.
There's basically two ways you can do it. You can either have the child thread wait for the child process before it exits, or you can pass the PID of the child process to the parent thread so it can wait for it. Here's the first approach:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *thread_fun(void *arg);
int main(void) {
pthread_t thread;
pthread_create(&thread, NULL, thread_fun, NULL);
pthread_join(thread, NULL);
return 0;
}
void *thread_fun(void *arg) {
pid_t pid = fork();
if(pid) {
printf("In Parent\n");
waitpid(pid, NULL, 0);
pthread_exit(NULL);
} else {
printf("In Child\n");
exit(0);
}
}
And here's the second:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
struct locked_pid {
sem_t sem;
pid_t pid;
};
void *thread_fun(void *arg);
int main(void) {
pthread_t thread;
struct locked_pid s;
sem_init(&s.sem, 0, 0);
pthread_create(&thread, NULL, thread_fun, &s);
sem_wait(&s.sem);
waitpid(s.pid, NULL, 0);
pthread_join(thread, NULL);
sem_destroy(&s.sem);
return 0;
}
void *thread_fun(void *arg) {
pid_t pid = fork();
if(pid) {
struct locked_pid *s = arg;
s->pid = pid;
sem_post(&s->sem);
printf("In Parent\n");
pthread_exit(NULL);
} else {
printf("In Child\n");
exit(0);
}
}
Note that the first is much simpler than the second. This is because in the second, you need a semaphore so that the parent process knows when the child PID gets written.
By the way, there's two things you should know about this code before you use it in anything important:
It doesn't have any error-checking, even though most of the functions it uses can fail.
POSIX says "If a multi-threaded process calls fork() ... the child process may only execute async-signal-safe operations until such time as one of the exec functions is called." This means that you shouldn't be doing printf("In Child\n");.
I am wondering if the following code can create zombies:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int i=1;
pid_t p;
p = fork();
i++;
if(p!=0){
waitpid(p, NULL, 0);
}
printf("%d\n",i);
return 0;
}
So, the parent process calls the waitpid for the child process, which returns immediately if the child has not already exited. So, no zombies can arise so far. But, if the child exits before return 0; command this would be a zombie then? I am actually confused about it. Should the waitpid be the last line of code before the program terminates? Any help would be appreciated. Thanks!
The child only becomes a zombie if it ends and the parent doesn't call wait*() as long as itself lives on.
In the moment the parent also ends the child is reaped by the init process which will take care to call wait*() on the child, so it will finally end and with this leave the zombie state and disappears from the process list.
To provoke the child created in your example code to become a zombie modify the code for example as follows:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t p = fork();
if (p != 0)
{
waitpid(p, NULL, 0); /* See if the child already had ended. */
sleep(1); /* Wait 1 seconds for the child to end. And eat away the SIGCHLD in case if arrived. */
pause(); /* Suspend main task. */
}
else
{
sleep(3); /* Just let the child live for some tme before becoming a zombie. */
}
return 0;
}
Due to the two following facts:
the child sleeps for 3s so the parent's call to waitpid() most probably will always fail
the default handling of SIGCHLD is to ignrore it.
the code above in fact is the same as:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t p = fork();
if (p != 0)
{
pause(); /* Suspend main task. */
}
else
{
sleep(3); /* Just let the child live for some tme before becoming a zombie. */
}
return 0;
}
I found a simple way to create a zombie process and test it using ps -e
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void main()
{
pid_t pid;
pid = fork();
//parent sleeps while the child has exited
//not an orphan since parent still alive
//child will be still present in process table
if(pid==0)
{//child
exit(0);
}
else
{//parent
sleep(15);
}
}
run ps -e while within the 15 seconds...
you will see
6454 pts/2 00:00:00 a.out < defunct >
I'm having trouble with a process forking exercise. I want to fork a child process and have it hang after announcing it has been forked, and wait for a signal to terminate, after which the parent process must announce it is terminating and then exit.
I can get the processes forked and have the parent wait for the hanging child to be killed by the signal, but it seems to kill the parent as well. I tried killing the child process specifically by its PID, but with no success.
Thanks for any help!
Code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
void catchInt (int signum)
{
printf("\nMy sincerest apologies, master\n");
/*kill(0, SIGINT);*/
exit(0);
}
void ignoreInt (int signum)
{
wait(NULL);
}
int main () {
pid_t pid;
/* fork process */
pid = fork();
if (pid < 0) /* error handler */
{
fprintf(stderr, "Fork Failed");
exit(-1);
}
else if (pid == 0) /* child */
{
printf("Child reporting in\n");
signal(SIGINT, catchInt);
for ( ;; )
pause();
}
else /* parent */
{
/* parent will wait for the child to complete */
signal(SIGINT, ignoreInt);
wait(NULL);
printf("You're welcome\n");
exit(0);
}
}
Even assuming you fix the code so it compiles (you've not defined tempPID), there are problems:
You set the child to go to sleep until a signal arrives.
You set the parent to wait until the child dies.
So, you have a state where neither process is going to do anything more.
You probably need the parent to send a signal to the child:
kill(pid, SIGINT);
It is not clear that you need the parent to set a signal handler.
You probably want the child to set a signal handler.
You probably don't want the infinite loop in the child.
Oh, and void main() is incorrect - int main() or int main(void) or int main(int argc, char **argv) are the approved declarations for main().
And it is tidier if you return a value (0) from main(). The C99 standard does permit you to drop off the end of main() and will treat that as returning zero, but only if the function is properly declared as returning an int.
The header for wait() and relatives in POSIX is <sys/wait.h>.
And, because I'm a sucker, here's code that compiles and might even do what you want:
#include <stdio.h>
#include <signal.h>
#include <unistd.h> /* getpid() */
#include <stdlib.h>
#include <sys/wait.h>
void catchInt(int signum)
{
printf("Child's PID is %d\n", (int)getpid());
printf("My sincerest apologies, master\n");
exit(1);
}
int main()
{
pid_t pid = fork();
if (pid < 0) /* error handler */
{
fprintf(stderr, "Fork Failed");
exit(-1);
}
else if (pid == 0) /* child */
{
printf("Child reporting in\n");
signal(SIGINT, catchInt);
pause();
}
else /* parent */
{
sleep(1);
kill(pid, SIGINT);
wait(NULL);
printf("You're welcome\n");
}
return(0);
}
Just figured out what I was doing wrong, I should have realized SIGINT is sent to every process, and so the parent was simply being sent an unhandled SIGINT, causing it to exit. Thanks for all the help (my apologies on the sloppy coding, I really shouldn't wait until the program is completed to clean that up), the code's been edited above and works as intended.
Thanks again.