I am sorry I am repeating a question https://stackoverflow.com/questions/5687837/monitor-implementation-in-c but not getting a solution as yet. I have probably asked the question incorrectly.
Say I have a code portion B. A parent process spawns a number of child processes to execute code B but I would like only one process to be inside code portion B at a time. How can I do it in C on Linux platform?
Thanks for your help
An edit. Not threads but process.
You want a mutex.
pthread_mutex_t mutexsum;
pthread_mutex_init(&mutexsum, NULL);
pthread_mutex_lock (&mutexsum);
// Critical code
pthread_mutex_unlock (&mutexsum);
If you are serious about it being multiple processes instead of multiple threads, the mutex needs to be stored in a shared memory segment.
So what you want is to have exactly one child running at any point of time, then why spawn all the children processes all at once?
When a child process ends, a SIGCHLD is issued, you can write your own handler for this signal and call spawn from the handler. Then you have one new child process created when one perishes -- only one child process running. Below is a hack (useless, just for demo) to achieve this:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void spawn(void){
pid_t child_pid=fork();
if(child_pid > 0){
printf("new child created by %d !\n",getpid());
sleep(1);
}else if(child_pid == 0){
printf("child %d created !\n",getpid());
}else{
exit(EXIT_FAILURE);
}
}
void handler(int sigval){
spawn();
}
int main(void){
signal(SIGCHLD,handler);
spawn();
return 0;
}
Related
I am working on a interactive C shell and outputting user CPU time and system CPU time of child process after executing fork. I use .tms_cutime and .tms_cstime but the output is negative. If I check using clock(), both outputs become 0s, no matter what code is run.
I got user time is -0.010000s and system time is -1400864714735.760010s.
Update: I tried to put times(&child_time_start); before fork() or wait(NULL). Both give me 0.00000s which is wrong. May I ask how to solve?
Below is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/times.h>
int main(void) {
struct tms child_time_start, child_time_end;
int clock_tick;
clk_tk = sysconf(_SC_CLK_TCK);
while (1){
pid_t pid = fork();
//child process
if (pid == 0){
times(&child_time_start); //start time count in child process
execlp("/bin/ls", "ls", (char *) 0);
printf("not successful");
exit(1);
}
//parent process
else{
wait(NULL);
times(&child_time_end); //end time counting
printf("child user time is %f s child system time is %f s\n", (double) (child_time_end.tms_cutime - child_time_start.tms_cutime) / clk_tk, (double) (child_time_end.tms_cstime - child_time_start.tms_cstime) / clk_tk);
}
}
return (0);
}
The child process is a copy of the parent process, but does not share its variables with it - instead, it starts with a copy of the parents variables. For that reason, the line
times(&child_time_start); //start time count in child process
must be executed by the parent process before or after the fork. If you place it between fork and if (pid==0) {, both processes will execute it, which could be useful in some cases, and it removes the time required to do the fork from the time measurement. If you place it before the fork, only the parent process will execute it but the child process gets a copy, so both have exactly the same value here.
I have a C program that uses fork-execv to create a child process to run a Python program. I want the parent and child processes to communicate through IPC (for example, FIFOs) and the child process will continue running for the duration of the parent process, performing Python functions for the parent at intervals signalled through IPC.
My problem is that once the child process starts it prevents the C program from running, so there is no opportunity for the two to interact. The C program is created on the main thread, not with a new thread created with pthreads.
It looks like the solution is to use clone() instead of fork(), which is also helpful because I want the two programs to share the same heap, which I can't do with fork().
The Python child process runs in a while True loop to keep it running while the parent process proceeds. Here is a very simplified version for the purpose of illustration (without IPC):
#!/usr/bin/python3
import os
import time
a = 0
while True:
a = a + 1
if a > 50000:
a = 0
time.sleep(1)
The C program for fork-execv:
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
int call_PyFn(int64_t fdx)
{
//Create buffer for file descriptor
int buflen = (int)((ceil(log10(fdx))+1)*sizeof(char));
char fdbuf[buflen];
sprintf(fdbuf, "%d", (int)fdx);
int status;
char * paramsList[] = {
"/usr/bin/python3",
"-m",
"NLTK_Python_Libs",
"-c",
fdbuf,
(char *)NULL };
if ( fork() == 0 ){
printf("I am the child\n");
execv(paramsList[0],paramsList); }
else {
printf("I am the parent\n");
wait( &status ); }
return 0;
}
My questions are:
Will clone() run the child process on a separate thread?
When I do multithreading work I use pthread_setaffinity to pin each thread to a specific core. Can I do that with clone()? From the docs, "If CLONE_THREAD is set, the child is placed in the same thread group as the calling process" but "without specifying CLONE_THREAD, then the resulting thread is placed in a new thread group whose TGID is the same as the thread's TID." https://linux.die.net/man/2/clone. That doesn't completely answer this question re affinity. Ideally I would like the two processes to run on the same core so that if I use this in a multicore project I can have each core run its own cloned process on the second thread of the parent's core.
I've read a lot of information on this but nothing completely clears it up for me. In the scenario described, am I right that fork does not create a new thread, which results in the child process blocking the parent, whereas clone will create a new thread?
It looks like the answer is yes, but confirmation would help. The question at How to create a real thread with clone() on Linux? comes close, but doesn't clear up all my questions.
Thanks.
This question already has answers here:
Create zombie process
(2 answers)
Closed 1 year ago.
my task is to create zombie process. My code looks like this:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("error\n");
}
else if (pid == 0) {
printf("Child %d\n", getpid());
printf("Parents %d\n", getppid());
printf("Waiting for my Child to complete\n");
exit(0);
}
else {
sleep(5);
printf("Parent %d\n",getpid());
}
return 0;
}
When I gcc and execute the file with ./a.out I get the following output:
Child 25097
Parents 25096
Waiting for my child to complete
Parent 25096 ( a few seconds later)
My task is to create a zombie process and print out the exit-state of the child process while being in parent process. Everything is a bit confusing to me because its the first time for me using Linux and C.
Do you have some tips/ hints for me, how to solve the task? Cause I'm not sure if everything is right. I also tried playing with wait(), waitpid() and WEXITSSTATUS(), but I'm not sure about it. And I used the ps x command to check if there is a different output but I didn't notice any changes.
Thanks in advance :)
This code will successfully create a zombie process.
After the call to fork, the child prints a few lines and exits, while the parent sleeps for 5 seconds. This means you'll have a zombie process for about 5 seconds while the parent is sleeping.
When the sleep is done, the parent prints something and exits. Once the parent exits the child is inherited by the init process, which will wait for the child and make it's pid disappear fro the pid list.
You can also use wait in the parent process, in which case the child is a zombie up until the parent calls wait.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to make function that does 'receiver' work(as parent process) and 'transmitter' work(as child process).
I wrote 'pid_t got_pid = wait(NULL); ' at parent process so that 'transmitter'(child process) work does its job before 'receiver' work.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
void foo(num){
static int fd[2];
static pid_t pid;
pipe(fd);
pid=fork();
if (pid<0){
printf("fork error\n");
return;
}
//parent process
else if(pid>0){
pid_t got_pid = wait(NULL);
printf("receiver\n");
}
//child process
else{
printf("transmitter\n");
}
}
int main(){
foo(0);
foo(1);
foo(2);
foo(3);
}
I called foo() 4 times at main() function and I was expecting to see results like
transmitter
receiver
transmitter
receiver
transmitter
receiver
transmitter
receiver
but i get results like this.
I understand that wait() function makes parent process waits for child process to finish,
How should I write code to make child process and parent process do their job for only the times that I called in main?
During the first call to makePipe the child writes transmitter, does the rest of its job, and returns to main. The next call to makePipe is executed by both original process and the child. Ditto for the remaining calls. That's why you have that many transmitters (and receivers too).
As for
why functions that I called in main() starts faster than remaining parent process
the answer is "just because". Unless you do explicit synchronization, nothing is guaranteed order-wise. You may encounter any sequence of events.
So i was experimenting on how to use fork and semaphores for a homework and it seems everytime i run the program fork always returns a number >0, while what i wanted was to first have several processes be made then be stopped using semaphores and then have some of them restart again.
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
int main(int argc,char *argv[])
{
int i,count;
count = 0;
pid_t *Pc;
Pc=(pid_t *) malloc((argc-2)*sizeof(pid_t));
sem_t *sem;
sem = (sem_t *) malloc((argc-2)*sizeof(sem_t));
for (i = 0; i <= argc-2; i++){
sem_init(&sem[i], 0, 0);
}
for (i =0; i<=argc-2; i++){
Pc[i] = fork();
if (Pc[i] == 0){
printf(" child");
sem_wait(&sem[i]);
printf("Experiment was a success!");
}
if (Pc[i]>0){
printf("Parent");
}
}
for (i =0; i<=argc-2; i++){
if (Pc[i] > 0)
count++;
}
for (i= 0; i<=3; i++){
if ( count == argc-2){
sem_post(&sem[i]);
}
}
}
nameofprogram 1 2
prints: Parent
Child
Parent
Child
You need to read the man page for sem_init(). The type of semaphore you are creating right now is not shared across processes. This requires a non-trivial change to your program, because you also need to set up shared memory. Refer to this question for a lengthy explanation of how to make your program work.
When a program calls fork, a new process is created with a new exact copy of the memory space. This mean that sem in your child process is not the same as sem in your parent process. So, when you call sem_post, you child process can not be notified of the change and get out of the wait function.
To solve this, you have different possibilities:
Create a shared memory which can be read by all your processes and create this semaphore in this shared memory, as already suggested.
Use named semaphores with sem_open. This kind of semaphore can be shared across different processes as it work like a file handle. This seems to be an easier way if you only need a shared semaphore (example here). You will have to generate a unique name for each semaphore in your array (may be only one semaphore on which you call sem_post multiple times would be enough for your use).
Keep your semaphores and use threads instead of processes (but I guess your homework is about processes so this may not be an option for you)