I have a process P which has to keep track of a list of processes P1 to Pn.
The program is initialized with P1, the head of the list, already created. On a specific event (not in the scope of the question), P has to write trough a pipe to the current last process Pi in the list and this process, upon receiving the message, has to fork. The newly created Pi+1 has to be added to a linked list managed by P as the new last process.
The way I'm trying to implement this is the following:
- P initializes an empty linked-list List, creates a pipe childs_to_p to receive messages from all descendants, creates a pipe fd, forks P1 and appends it to List.
- P1 starts listening on fd.
- If P wants to add another process, it creates a new pipe fd2, and through fd it communicates to P1 (the last process in List for this first iteration) the reading end of fd2 (the reading end that P2 will have to listen from).
P1 reads from fd, forks and tells the newly created P2 the reading end of fd2. Then continues to listen for instructions on fd.
P2 sends its pid to P through the pipe childs_to_p.
- P adds P2'pid to List.
- Repeat n times.
Keep in mind that I'm new to C language, but here's what I implemented so far.
This is the initialization of P:
void setupProcessManager(int we, int re, int msg_size) {
write_to_m = we; // Setup of pipe to external
read_from_m = re; // process that gives instructions
message_size = msg_size; // to P.
initList(&l); // Linked list initialization
open_childs_to_pm_pipe(); // Open pipe to read from processes in list
addp1(); // Initialize P1
pthread_t t;
pthread_create(&t, NULL, PMListen, NULL); // P starts listening from external process
pthread_join(t,NULL); // Wait for thread termination
close(write_to_m); // Close pipe to external process
close(read_from_m); // Close pipe from external process
}
The function to initialize P1:
void addp1() {
int to_p1[2];
pipe(to_p1); // Create new pipe to P1
pid_t pid = fork(); // Fork P1
if(pid == 0) {
PListen(to_p1[0]); // P1 starts listening
exit(0);
} else if(pid>0) {
insertEnd(&l, pid, to_p1[1], to_p1[0]); // P appends P1 to list
}
}
The function performed by P (consider only the 'A' case in the switch):
void *PMListen() {
int message;
int listen = 1;
while(listen) {
read(read_from_m,&message,message_size);
switch(message) {
// OTHER CASES
case 'A':
int new_pipe[2]; // P creates a new pipe
pipe(new_pipe);
write(getLastProcessWritingEnd(&l), &new_pipe[0], message_size); // P writes reading end of new pipe to P1
pid_t pid;
read(childs_to_pm[0], &pid,sizeof(pid_t)); // P reads P2 pid from childs_to_p
insertEnd(&l, pid, new_pipe[1], new_pipe[0]); // P appends P2 to list
break;
}
}
}
And finally the task performed by the processes in the list:
void PListen(int read_from_here) {
int message;
int listen = 1;
while(read(read_from_here,&message,message_size) != 0) {
switch(message) {
default: // Pi reads integer (reading end of pipe P-Pi+1)
pid_t pid = fork(); // Fork Pi+1
if(pid == 0) {
pid_t mypid = getpid();
write(childs_to_pm[1], &mypid, sizeof(int)); // Pi+1 writes its pid to P through childs_to_p
PListen(message); // Pi+1 starts listening on its pipe from P
exit(0);
}
break;
}
}
}
Everything works as intended. P1 is created and added to the linked list. When P tries to add P2 it does so but then the function PListen keeps looping, forking forever.
I know the code is not well written, but as I mentioned I'm not familiar with C. I need help with the algorithm rather than with the beauty of the code.