Child and Parent pid with fork(); - c++

I'm trying to make a program which make 9 child process, so I use fork 9 times only if we are the father, like this:
for (int i = 0; i < 9; i++) { // Creo 9 hijos.
if (child_pid > 0) {
child_pid = fork();
childs[i] = child_pid;
}
if (child_pid < 0)
printf("Error...\n");
}
Now, I have to print on each children what children he is, starting from 0, so I was thinking about this:
printf("This is child #%d\n", getpid() - getppid());
But I'm not sure, Does this always work?, What if while the parent is creating childrens the operating system creates another process?, the number of children will be discontinued?.
And finally, if the answer is yes, how can I make that the #n children knows that he is the children number n?.

You can use the i variable to tell which child you are in, but the logic of your loop is incorrect. It should go like this:
for (int i = 0; i < 9; ++i) {
child_pid = fork();
if (child_pid == 0) {
// We are the child. The value of the i variable will tell us which one.
// If i == 0 we are the first child, i == 1 and we are the second, and so on.
printf("We are child #%d\n", i);
exit(EXIT_SUCCESS);
}
if (child_pid < 0) {
// Forking failed.
perror("fork()");
exit(EXIT_FAILURE);
}
// Otherwise we are the parent and forking was successful; continue the loop.
}
The operating system is not required to assign process IDs in sequential order. If another process is using the next one, it would be skipped over in a sequential assignment method, but the OS could really assign a random number as the pid as long as it is not in use.

Related

How to convert the system call to fork in C++ linux

This is the code for playing sound file in C++ linux code
string str1 = "aplay ";
str1 = str1 + " out.wav" + " & ";
const char *command = str1.c_str();
system(command);
** Entire code is available here : Playing sound C++ linux aplay : device or resource busy
I just want to know how to play this in a fork() as I read that system call is too taxing on cpu, which ofcourse is in my case.
Please help
fork will make a copy of your process, so you can easily write:
// fork the current process: beyond this point, you will have 2 process
int ret = fork();
if (ret == 0) {
// in child: execute the long command
system("aplay out.wav");
// exit the child process
exit(0);
}
// child process will not go here
if (ret < 0) {
perror("fork");
}
After, you should know that system will do for you fork + exec + wait. Since you don't want your parent process to wait the child, you can write:
// fork the current process: beyond this point, you will have 2 process
int ret = fork();
if (ret == 0) {
// in child: execute the long command
char program[] = "/usr/bin/aplay";
char *args[] = {"/usr/bin/aplay", "out.wav" };
ret = execv(program, args);
// this point will be reach only if `exec` fails
// so if we reach this point, we've got an error.
perror("execv");
exit(0);
}
// child process will not go here
if (ret < 0) {
perror("fork");
}

How to make Two processes to complete one task, and whose finish task first, terminate another one

I am looking for a good way to create 2 equally child processes, which will complete 1 task - to sort separately, one from the other, an array with numbers data with different algorithms for example Merge-Sort, and QuickSort.
The first process, which completed the task, should terminate another one (and print result)
Also which will be the best way to transfer data to processes (Pipes?)
Also is there something I didn't take into account?
I should use system functions, Posix and Linux based code
int main() {
pid_t child_a, child_b;
int unsortedData[MAX] = getNumericDataFromFile(/*filename*/);
// Open two pipes for communication
// The descriptors will be available to both
// parent and child.
int in_fd[2];
int out_fd[2];
if (pipe(in_fd) == -1) { // For child's stdin
fprintf(stderr, "Pipe In Failed");
return 1;
}
if (pipe(out_fd) == -1) { // For child's stdout
fprintf(stderr, "Pipe Out Failed");
return 1;
}
if ((child_a = fork()) < 0) { // create first child process
fprintf(stderr, "Fork of first child process Failed");
return 1;
}
if (child_a == 0) {
/* Child A code, execute first algorithm */
int sortedData[MAX] = firstChildProcess(/*unsortedData*/);
/* terminate other process properly if its firs ? */
} else {
if ((child_b = fork()) < 0) { // create second child process
fprintf(stderr, "Fork of second child process Failed");
return 1;
}
if (child_b == 0) {
/* Child B code, execute second algorithm */
int sortedData[MAX] = ChildProcess(/*unsortedData*/)
/* terminate other process properly if its first? */
} else {
parentCode(..);/* Parent Code */
}
}
return 0;
}
Input : 6, 5, 4, 3, 2, 1
Output: Second algorithm finished first sorting task with result:
1, 2, 3, 4, 5, 6
Thank you in advance

child process hanging while reading from stdin (fork/dup2 race condition)?

I have a process that forks in order to execute a subprocess, which receive an entry from stdin and writes to stdout.
My code in short is as follows:
int fd[2];
int fd2[2];
if (pipe(fd) < 0 || pipe(fd2) < 0)
throws exception;
pid_t p = fork();
if (p == 0) // child
{
close(fd[0]); //not needed
dup2( fd[1],STDOUT_FILENO);
dup2( fd[1],STDERR_FILENO);
close(fd2[1]); //not needed
//what if write calls on parent process execute first?
//how to handle that situation
dup2( fd2[0],STDIN_FILENO);
string cmd="./childbin";
if (execl(cmd.c_str(),(char *) NULL) == -1)
{
exit (-1);
}
exit(-1);
}
else if (p > 0) // parent
{
close(fd[1]); //not needed
close(fd2[0]);
if (write(fd2[1],command.c_str(),command.size())<0)
{
throw exception;
}
close(fd2[1]);
//waits for child to finish.
//child process actually hangs on reading for ever from stdin.
pidret=waitpid(p,&status,WNOHANG))==0)
.......
}
The child process remains waiting forever for data in STDIN. Is there maybe a race condition between the child and parent process? I think that could be the problem but not quite sure and also not sure how to fix it.
Thanks in advance.
Update:
Some useful information.
The parent process is a daemon and this code runs several times per second. It works 97% of the times (~3% of the cases, the child process remains in the state described before).
UPDATE 2
After added validation in dup2 call, there is no error there, next condition is never raised.
if(dup2(...) == -1) {
syslog(...)
}
Your missing a wait that is why you in 3% of the cases run the parent before the child. See the example at the bottom.
Also you should call close on the fd's you don't use before doing anything else.

Understanding unix child processes that use semaphore and shared memory

I'm going to do my best to ask this question with the understanding that I have.
I'm doing a programming assignment (let's just get that out of the way now) that uses C or C++ on a Unix server to fork four children and use semaphore and shared memory to update a global variable. I'm not sure I have an issue yet, but my lack of understanding has me questioning my structure. Here it is:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define NUM_REPEATS 10
#define SEM_KEY 1111
#define SHM_KEY 2222
int globalCounter = 0;
/***** Test function for confriming a process type ******/
int checkProcessType(const char *whoami)
{
printf("I am a %s. My pid is:%d my ppid is %d\n",
whoami, getpid(), getppid() );
for(int i = 1; i<=3; i++){
printf("%s counting %d\n", whoami, i);
}
return 1;
}
void
int main (void) {
pid_t process_id; // PID (child or zero)
int sharedMemID; // Shared memory ID
int sharedMemSize; // shared memory size
struct my_mem * sharedMemPointer; // pointer to the attached shared memory
// Definition of shared memory //
struct my_mem {
long counter;
int parent;
int child;
};
// Gathering size of shared memory in bytes //
sharedMemSize = sizeof(my_mem);
if(sharedMemSize <= 0){
perror("error collection shared memory size: Exiting...\n");
exit(0);
}
// Creating Shared Memory //
sharedMemID = shmget(SHM_KEY, sharedMemSize, 0666 | IPC_CREAT);
if (sharedMemID < 0) {
perror("Creating shared memory has failed: Exiting...");
exit(0);
}
// Attaching Shared Memory //
sharedMemPointer = (struct my_mem *)shmat(sharedMemID, NULL, 0);
if (sharedMemPointer == (struct my_mem*) -1) {
perror("Attaching shared memory has failed. Exiting...\n");
exit(0);
}
// Initializing Shared Memory //
sharedMemPointer->counter = 0;
sharedMemPointer->parent = 0;
sharedMemPointer->child = 0;
pid_t adder, reader1, reader2, reader3;
adder = fork();
if(adder > 0)
{
// In parent
reader1 = fork();
if(reader1 > 0)
{
// In parent
reader2 = fork();
if(reader2 > 0)
{
//In parent
reader3 = fork();
if (reader3 > 0)
{
//In parent
}
else if (reader3 < 0)
{
// Error
perror("fork() error");
}
else
{
// In reader3
}
}
else if(reader2 < 0)
{
//Error
perror("fork() error");
}
else
{
// In reader2
}
}
else if(reader1 < 0)
{
// Error
perror("fork() error");
}
else
{
// In reader1
}
}
else if(adder < 0 )
{
// Error
perror("fork() error");
}
else
{
// In adder
//LOOP here for global var in critical section
}
}
Just some info of what I'm doing (I think), I'm creating a hunk of shared memory that will contain a variable, lets call it counter that will strictly be updated by adder and by the parent which becomes a subtractor after all child processes are active. I'm still trying to figure out the semaphore stuff that I will be using so adder and subtractor execute in critical section, but my main question is this.
How can I know where I am in this structure? My adder should have a loop that will do some job (update global var), and the parent/subtractor should have a loop for its job (also update global var). And all the readers can look at any time. Does the loop placement for parent/subtractor matter? I basically have 3 locations I know I'll be in parent. But since all children need to be created first does it have to be in the last conditional after my third fork where I know I'm in parent? When I use my test method I get scattered outputs, meaning child one can be after parent's output, then child three, etc. It's never in any order, and from what I understand of fork that's expected.
I really have like three questions going on, but I need to first wrap my head around the structure. So let me just try to say this again concisely without any junk cause I'm hung up on loop and critical section placement that isn't even written up yet.
More directly, when does parent know the existence of all children and with this structure can one child do a task and somehow come back to it (i.e. adder/first child adding to global variable once, exits, and some other child can do its thing etc).
I still feel like I'm not asking the right thing, and I believe this is due to still trying to grasp concepts. Hopefully my stammering will kind of show what I'm stuck on conceptually. If not I can clarify.

Number of child running in c++

I am trying to create, a large number of child processes, say 200, with the following code. I would to print, before moving to the next child, how many childs are still running (out of the ones already created) and how many still to go. Can not to seem to be able to count active running child processes. Any help/hints?
int main ()
{
pid_t pid;
global_process_count = 0, max_process_count = 200;
while (global_process_count < max_process_count)
{
if ((pid = fork()) < 0)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
// Child process
exit(EXIT_SUCESS);
}
++global_process_count;
}
}
Well, you should also count children exits. A parent process receive a signal (SIGCHLD) everytime a child process terminates (successfully or not). You should set up a signal handler and upon receive a signal gets child's exit code by invoking wait(). See "example 3" here
You want the group id of these processes. A system call will tell you the number of processes in that group.