int main(int argc, char *argv[]) { int nproc; /* * For each of argv[1] to argv[argc - 1], * create a new child process, add it to the process list. */ nproc = 0; /* number of proccesses goes here */ /* Wait for all children to raise SIGSTOP before exec()ing. */ wait_for_ready_children(nproc); /* Install SIGALRM and SIGCHLD handlers. */ install_signal_handlers(); if (nproc == 0) { fprintf(stderr, "Scheduler: No tasks. Exiting...\n"); exit(1); } /* loop forever until we exit from inside a signal handler. */ while (pause()) ; /* Unreachable */ fprintf(stderr, "Internal error: Reached unreachable point\n"); return 1; }
int main(int argc, char *argv[]) { pid_t pid; int status; struct tree_node *root; if (argc != 2) { fprintf(stderr, "Usage: %s <input_tree_file>\n\n", argv[0]); exit(1); } root = get_tree_from_file(argv[1]); print_tree(root); pid=fork(); if(pid<0){ perror("main: fork"); exit(1); } else if(pid==0){ fork_procs(root); exit(1); } wait_for_ready_children(1); show_pstree(pid); kill(pid,SIGCONT); pid=wait(&status); explain_wait_status(pid,status); return 0; }
//--ENTRY POINT-- int main (int argc, char *argv[]) { if (argc!=2) { fprintf(stderr, "Invalild number of arguments.\n"); return 1; } node_type *root; root=get_tree_from_file(argv[1]); pid_t FIRST; int status; FIRST=fork(); if (FIRST<0) { fork_err(getpid()); exit(EXIT_FAILURE); } if (FIRST==0) { //Process Tree R00T: create_ptree(root, 0); exit(EXIT_SUCCESS); } else { //MAIN: wait_for_ready_children(1); //All children are in slumber! show_pstree(FIRST); kill(FIRST, SIGCONT); if ((wait(&status))==-1) { sign_err(FIRST, "main"); exit(EXIT_FAILURE); } else { explain_wait_status(FIRST, status); } } return 0; }
//--FUNCTIONS-- void create_ptree(node_type *cur, size_t lvl) { int status; pid_t *CHILDREN=NULL; //Children PID array. if (cur->nr_children>0) { //Allocation of children PID array memory. CHILDREN=(pid_t *)malloc((cur->nr_children)*sizeof(pid_t)); if (CHILDREN==NULL) { alloc_err; exit(EXIT_FAILURE); } } pid_t par=getpid(), child=0, retv=0; change_pname(cur->name); //Change name. // proc_enter(par); //Enter message. size_t i=0; for (i=0; i<cur->nr_children; i++) { //Create heirs. // fprintf(stderr, "FORK LV: %u - IT: %u\n", lvl, i); //DEBUG child=fork(); if (child<0) { //Sanity. fork_err(cur); exit(EXIT_FAILURE); } if (child==0) { //Recursion for child: create_ptree(&cur->children[i], lvl+1); //... } else { //Rest of parent: CHILDREN[i]=child; continue; } } if (cur->nr_children>0) { //Node: //Wait for heirs to sleep. wait_for_ready_children(cur->nr_children); } //else //Leaf: Fall-through. if (raise(SIGSTOP)) { //Sleep yourself. sign_err(par, "0"); exit(EXIT_FAILURE); } actual_msg(par, cur->name); //Wake-up and print awake message. // fprintf(stderr, "i=%u, child=%ld, CHILDREN[i]=%ld\n", i, (long)child, (long)CHILDREN[i]); if (cur->nr_children>0) { for (i=0; i<cur->nr_children; i++) {//Parents continue and bury their children 1 by 1. cont_msg(cur->name, CHILDREN[i]); if ((kill(CHILDREN[i], SIGCONT))==-1) { sign_err(par, "1"); exit(EXIT_FAILURE); } // wait_for_ready_children(1); //NEEDs DEBUGGING: Doesn't work with this instead of the 2 next commands. retv=wait(&status); //Wait the just awoken child to terminate before you wake up the next (condition for the depth first traversal). bury_msg(cur->name, retv); //Bury message. } } //else //Fall-through. // proc_exit(par); //Exit message. // kill(par, SIGKILL); exit(EXIT_SUCCESS); //Children and parents who buried theirs, just roll off and die. }
int main(int argc, char *argv[]) { pid_t p; int i; /* * For each of argv[1] to argv[argc - 1], * create a new child process, add it to the process list. */ current = 0; /* current proccess number goes here */ nprog = argc - 1; /* number of proccesses goes here */ childid = malloc((nprog)*sizeof(int)); alive = malloc((nprog)*sizeof(int)); for (i=0; i < nprog; i++){ printf("forking..%d %d\n", argc, i); p = fork(); //if (p<0)... if (p == 0){ do_child(argv[i+1]); } else{ childid[i] = (int) p; alive[i] = 1; } } /* Wait for all children to raise SIGSTOP before exec()ing. */ wait_for_ready_children(nprog); /* Install SIGALRM and SIGCHLD handlers. */ install_signal_handlers(); if (nprog == 0) { fprintf(stderr, "Scheduler: No tasks. Exiting...\n"); exit(1); } else{ alarm(SCHED_TQ_SEC); kill(childid[0], SIGCONT); } /* loop forever until we exit from inside a signal handler. */ while (pause()) ; /* Unreachable */ fprintf(stderr, "Internal error: Reached unreachable point\n"); return 1; }
void fork_procs(struct tree_node *root) { pid_t child ; int i,status ; pid_t* children; children = (pid_t*)malloc((sizeof(pid_t)*root->nr_children)); if (children == NULL){ fprintf(stderr, "allocate children failed\n"); exit(1); } printf("PID = %ld, name %s, starting...\n",(long)getpid(), root->name); change_pname(root->name); for (i = 0 ; i < root->nr_children; i++){ printf("%s:Creating child %s...\n",root->name,root->children[i].name); child = fork(); if (child < 0) { perror("child fork"); exit(1); } if (child == 0) { /* Child */ fork_procs(&root->children[i]); } /* Father saves child's pid ! */ children[i] = child; } wait_for_ready_children(root->nr_children); printf("%s: All children ready ! Suspending with SIGSTOP...\n",root->name); /* * Suspend Self */ raise(SIGSTOP); printf("PID = %ld, name = %s is awake\n",(long)getpid(), root->name); for (i = 0 ; i < root->nr_children;i++){ printf("%s: Activating child %s...\n",root->name,root->children[i].name); kill(children[i],SIGCONT); children[i] = wait(&status); explain_wait_status(children[i],status); } printf("%s: Exiting...\n",root->name); free(children); exit(0); }
int main(int argc, char *argv[]) { pid_t pid; int status; struct tree_node *root; if (argc < 2){ fprintf(stderr, "Usage: %s <tree_file>\n", argv[0]); exit(1); } /* Read tree into memory */ root = get_tree_from_file(argv[1]); /* Fork root of process tree */ pid = fork(); if (pid < 0) { perror("main: fork"); exit(1); } if (pid == 0) { /* Child */ fork_procs(root); exit(1); } /* * Father */ /* for ask2-signals */ wait_for_ready_children(1); /* Print the process tree root at pid */ show_pstree(pid); /* for ask2-signals */ kill(pid, SIGCONT); /* Wait for the root of the process tree to terminate */ pid = wait(&status); explain_wait_status(pid, status); return 0; }
void fork_procs(struct tree_node *current){ pid_t p_new[20]; int status; int i; struct tree_node *temp; change_pname(current->name); printf("%s:Starting..\n",current->name); for(i=0;i<current->nr_children;i++){ p_new[i]=fork(); if(p_new[i]<0){ perror("fork"); exit(2); } else if(p_new[i]==0){ fork_procs(current->children+i); } } wait_for_ready_children(current->nr_children); printf("%s:I gave birth to %d childs and then suspended myself..\n",current->name,current->nr_children); raise(SIGSTOP); printf("%s:Before you know,awake!..\n",current->name); for(i=0;i<current->nr_children;i++){ temp=current->children+i; printf("I, %s , am your father %s,and i say wake!\n",current->name,temp->name); kill(p_new[i],SIGCONT); p_new[i]=wait(&status); explain_wait_status(p_new[i],status); } printf("%s:Exiting..\n",current->name); exit(3); }