Пример #1
0
int main()
{
	char* argumentos[MAX_ARGS + 1];
	char buffer[BUFFER_SIZE];
	list = lst_new();
	int pid;
	pthread_t tid;
	pthread_mutex_init(&mutex, NULL);
	
	// Criar tarefa para monitorizar os filhos
	if(pthread_create(&tid, 0, tarefa_monitor,NULL) != 0) {
	  perror("Erro no pthread_create: ");
	  exit(EXIT_FAILURE);
	}
	while(1){
		if(readLineArguments(argumentos,MAX_ARGS,buffer,BUFFER_SIZE) <= 0){ 
			continue;
		}
		if(strcmp(argumentos[0],"exit")==0) {
			// exit - esperar pela tarefa monitora e imprimir as informacoes dos filhos
			pthread_mutex_lock(&mutex);
			exit_ative = true;
			pthread_mutex_unlock(&mutex);
			
			pthread_join(tid,NULL);
			lst_print(list);
			pthread_mutex_destroy(&mutex);
			exit(EXIT_SUCCESS);		
		
		}
		else {	
			pid = fork();
			time_t starttime = time(NULL);
			
			if (pid < 0) {
				perror("Erro no fork");
				continue;
			}
			
			if (pid == 0) {  // Codigo do filho
				execv(argumentos[0], argumentos);
				perror("Erro no execv:");
				exit(EXIT_FAILURE);
			}
			// Codigo do pai
			pthread_mutex_lock(&mutex);
			nfilhos++;
			insert_new_process(list,pid,starttime);
			pthread_mutex_unlock(&mutex);
		}	
	}
	return 0;
}
Пример #2
0
int main(int argc, char **argv){
	char buffer[BUFFER_SIZE];
	int numArgs;
	char *arg_vector[VECTOR_SIZE];
	time_t starttime;
	
	int child_pid;
	pthread_t monitor_thread;
	pthread_t writer_thread;
	lst = lst_new();
	writing_queue = new_queue();

	/* Initialize synchronization objects */
	pthread_mutex_init_(&mutex, NULL);
	pthread_cond_init_(&write_cond, 0);
	pthread_cond_init_(&max_par, NULL);
	pthread_cond_init_(&new_child, NULL);

	if ((log_fd = fopen("./log.txt", "a+")) == NULL){
		perror("[ERROR] opening log file");
		exit(EXIT_FAILURE);
	}
	read_log(); /* assign total time and iteration values for this execution */
	pthread_create_(&monitor_thread, NULL, (void *)&monitor, NULL); /* Create Monitor Thread */  
	pthread_create_(&writer_thread, NULL, (void *)&writer, NULL); /* Create Writer Thread */
 
	while (1) {
		numArgs = readLineArguments(arg_vector, VECTOR_SIZE, buffer, BUFFER_SIZE);
		if (numArgs <= 0)continue;

		if (strcmp(arg_vector[0], EXIT_COMMAND) == 0 ) {

			/* signal exit command */
			exit_command = 1;

			/* wait for monitor thread to end */
			pthread_cond_signal_(&new_child); /* must signal to catch exit flag */
			pthread_join_(monitor_thread, NULL);
			pthread_join_(writer_thread, NULL);

			/* print all the elements in the list */
			lst_print(lst);
			
			/* terminate sync objects */
			pthread_mutex_destroy_(&mutex);
			pthread_cond_destroy_(&write_cond);
			pthread_cond_destroy_(&max_par);
			pthread_cond_destroy_(&new_child);
			fclose(log_fd);
			lst_destroy(lst);
			exit(EXIT_SUCCESS);
		}

		/* while there are child process slots available launch new child process,
		* else wait here */
		pthread_mutex_lock_(&mutex);
		while (child_count >= MAXPAR) pthread_cond_wait_(&max_par, &mutex);
		pthread_mutex_unlock_(&mutex);

		child_pid = fork();
		if (child_pid < 0){ /* test for error in fork */
			perror("[ERROR] forking process");
			continue;
		}
		if (child_pid == 0){ /* execute on child */
			if (execv(arg_vector[0], arg_vector) == -1) {
			perror("[ERROR] executing program.");
			exit(EXIT_FAILURE);
			}
		}
		else { /* execute on parent */
			/* Main thread
			 *
			 * Child processes are inserted into the process list saving their pid
			 * and their start time.
			 * Child counter is incremented.
			 * The condition variable waiting for a new child process is signaled.
 			 */
			time(&starttime); /* get start time of child process */
			pthread_mutex_lock_(&mutex);
			insert_new_process(lst, child_pid, starttime);
			child_count++;
			pthread_cond_signal_(&new_child);
			pthread_mutex_unlock_(&mutex);
		}
	}
}
Пример #3
0
/*===================================================
=				Programa principal        			=
===================================================*/
int main()
{
	char* argumentos[MAX_ARGS];		//	Argumentos dos executáveis
	char buffer[BUFFER_SIZE];		//	Buffer que guarda os dados da leitura do pipe
	int input;		 				// 	Descritor de ficheiro para o pipe que recebe input dos terminais
	/**
	 * 	Inicializar as variáveis e estruturas da par-shell
	 */
	initialize_variables();	
	/**
	 * 	Atualizar as informações do log da par-shell
	 */
	update_log_values();
	/**
	 * 	Catch do signal ctrl+c
	 */
	if(signal(SIGINT, sig_handler) == SIG_ERR){
		perror("Erro no signal: ");
	}

    while(1){
    	/**
    	 * 	Abrir o pipe que recebe input dos terminais
    	 */
    	if((inputdesc = open(inputpipe,O_RDONLY)) < 0){
    		perror("Erro no open do pipe: ");
    		exit(EXIT_FAILURE);
    	} 
    	/**
    	 * 	Ler informações do pipe
    	 */
    	if((input = read(inputdesc,buffer,BUFFER_SIZE)) <= 0){
    		//	Fechar o pipe apos a leitura
    		close(inputdesc);
    		//	Não lê nada mas tambem não dá erro, continua o ciclo (e.g press enter) 
    		if(input == 0){
    			continue;
    		}
    		perror("Erro no read do input");
    	}
    	else{
    		buffer[input] = '\0';
			if(strcmp(buffer,"exit-global") == 0) {
				/**
				 * 	Sair da par-shell
				 */
				exit_par_shell();
			}
			
			if (sscanf(buffer, "/tmp/terminal-%d", &pidterminal) > 0) {
				/**
				 *	Registar um terminal especifico e o seu pipe
				 */
				printf("Terminal %d criado\n",pidterminal);
				if(fflush(stdout) < 0)
				    perror("Erro no fflush de escrita no par-shell na criação de terminal: ");
				//	Inserir pid do terminal na lista de terminais
				insert_new_terminal(lista_terminais,pidterminal);  
				continue;
			}
			
			if(sscanf(buffer,"stats %d",&pidterminal) > 0){
				/**
				 * 	Enviar o número de processos filhos em execução e 
				 *  o tempo total de execução da par-shell para o terminal
				 */
				//	Construir strings de output e do nome do pipe do terminal
				sprintf(output,"Número de filhos em execução: %d \nTempo total: %g",nfilhos,tempo_total_execucao);
				sprintf(terminalpipe,"/tmp/terminal-%d",pidterminal);
				//	Abrir o pipe do terminal para escrita
				if((fd_write = open(terminalpipe, O_WRONLY)) < 0){
					perror("Erro no open do stats da par-shell: ");
					exit(EXIT_FAILURE); 
				}    
				//	Escrever no pipe do terminal             
				if(write(fd_write,output,strlen(output)) < 0){
					perror("Erro no write do stats da par-shell: ");
				}
				//	Fechar o pipe do terminal
				if(close(fd_write) < 0){
					perror("Erro no close do stats da par-shell: ");
				}
				strcpy(output,"\0");
				continue;
			}
			else {
				int i;		//	Inteiro temporário usado no ciclo de processamento dos argumentos 
				int pid;	//	Pid do processo filho criado com fork
				/**
				 * 	Processar todos os argumentos que poderá receber
				 */
				argumentos[0] = strtok(buffer," ");
				for(i = 1; i < MAX_ARGS; i++){ 
					argumentos[i] = strtok(NULL," ");
				}
				/**
				 * 	Confirmar se podem ser criados filhos
				 */
				mutex_lock();
				while (! (nfilhos < MAXPAR))
					if(pthread_cond_wait(&podeCriarFilhos,&mutex) != 0){
						perror("Erro no pthread_cond_wait na par-shell: ");
					}
				mutex_unlock();

				/**
				 * 	Criar processo filho usando fork
				 */
				pid = fork(); 					
				//	Registar tempo de inicio do processo filho
				time_t starttime = time(NULL);  
				if (pid < 0) {
					perror("Erro no fork: ");
					continue;
				}
				/**
				 * 	Código do processo filho
				 */
				if (pid == 0) {  		
					// 	Redirecionar o output do processo filho		
					redirect_stdout();
					// 	Evitar que o ctrl+c se propague para o processo filho -> signal é ignorado
					signal(SIGINT,SIG_IGN);
					//	Trocar código do processo filho pelo do executável	
					if(execv(argumentos[0], argumentos) < 0){
						perror("Erro no execv:");
						exit(EXIT_FAILURE);
					}
				}
				/**
				 * 	Código do processo pai
				 */
				mutex_lock();		
				nfilhos++;
				if(pthread_cond_signal(&podeMonitorizar) != 0){
					perror("Erro no pthread_cond_signal na par-shell: ");
				}
				insert_new_process(list,pid,starttime);
				mutex_unlock();
			}
		}	
	}
	return 0;
}
Пример #4
0
/*////////////////////////////////////////////
/////////////// MAIN FUNCTION ////////////////
////////////////////////////////////////////*/
int main() {
	char* arg[7];
	char buffer[100], filename[100], fnamePipeStats[100];
	int vectorSize = 7, pid, numargs, fd, fDescPIPE, fDescPIPE_S;
	pthread_t waitChild;
	pid_t pidChild;
	terminalLst* terminals = new_terminal_lst();
	l = lst_new();
	if (pthread_mutex_lock(&mutex) != 0) {
		perror(error_mutex_lock);
	}
	if (pthread_mutex_unlock(&mutex) != 0) {
		perror(error_mutex_unlock);
	}
    
	if (pthread_mutex_init(&mutex, NULL) != 0){
		perror(error_mutex);
	}
	if (pthread_cond_init(&can_wait, NULL) != 0) {
		perror(error_cond_init_wait);
	}
	if (pthread_cond_init(&can_execute, NULL) != 0) {
		perror(error_cond_init_execute);
	}
	if (pthread_create(&waitChild, NULL, waitThread, NULL) != 0) {
		perror(error_thread_create);
		exit(EXIT_FAILURE);
	}
    if (signal(SIGINT, CTRLC) == SIG_ERR) {
        perror(error_signal);
    }
	unlink(PIPE); /*-------------------------------------------------*/

	if (mkfifo(PIPE, 0777) != 0) {
		perror(error_mkfifo);
		exit(EXIT_FAILURE);
	}
	if ((fDescPIPE = open(PIPE, O_RDONLY)) == -1) {
		perror(error_pipe_open);
		exit(EXIT_FAILURE);
	}

	close(0);
	dup2(fDescPIPE, 0);

	while (1) {

		numargs = readLineArguments(arg, vectorSize, buffer, 100);

		if(flag_signal)
			break;

		if (numargs <= 1) {
			continue;
		}
		
		if (pthread_mutex_lock(&mutex) != 0) {
			perror(error_mutex_lock);
		}
		while (numChildren == MAXPAR) {
            if (pthread_cond_wait(&can_execute, &mutex) != 0) {
                perror(error_cond_wait);
            }
		}
		if (pthread_mutex_unlock(&mutex) != 0) {
			perror(error_mutex_unlock);
		}
		else if (strcmp(arg[0], EXIT) != 0) {
			if (strcmp(arg[0], starter) == 0) {
				int pid_terminal = atoi(arg[1]);
				insert_terminal(terminals, pid_terminal);
				continue;
			}
			if (strcmp(arg[0], stats) == 0) { /*tratar o PID e meter na lista*/
				sprintf(fnamePipeStats, "%s-%s", PIPE_S, arg[1]);
                
                while((fDescPIPE_S = open(fnamePipeStats, O_WRONLY)) < 0);
                if(fDescPIPE < 0) {
					perror(error_pipe_open);
					exit(EXIT_FAILURE);
				}
				if (pthread_mutex_lock(&mutex) != 0) {
                    perror(error_mutex_lock);
                }

				sprintf (buffer, "Number of active children: %d\nTotal execution time to the moment: %d", numChildren, timeTotal);
				write(fDescPIPE_S, buffer, strlen(buffer));
                if (pthread_mutex_unlock(&mutex) != 0) {
                    perror(error_mutex_unlock);
                }

				close(fDescPIPE_S);
				continue;
			}

            if (strcmp(arg[0], EXITGLOBAL) == 0) { /* SONFOILULDNILDEFNC*/
                printf("1\n");
                CTRLC(SIGINT);
            }
			else {
				pid = fork();
				if (pid < 0) {
					perror(error_fork);
				}
				if (pthread_mutex_lock(&mutex) != 0) {
					perror(error_mutex_lock);
				}
				insert_new_process(l, pid, time(NULL));
				numChildren++;
				if (pthread_cond_signal(&can_wait) != 0) {
					perror(error_cond_wait);
				}
				if (pthread_mutex_unlock(&mutex) != 0) {
					perror(error_mutex_unlock);
				}
				if (pid == 0) {
					pidChild = getpid();
					sprintf(filename, "par-shell-%d.txt", pidChild);
					fd = open(filename,  O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
					close(1);
					dup(fd);
					close(fd);
					if (execv(arg[0], arg) < 0) {
						perror(error_execv);
						exit(EXIT_FAILURE);
					}
				}
				else {
					sprintf(filename, "par-shell-%d.txt", pid);
				}
			}
        }
        else {
            break;
        }
	}
	isExit = true;
    if (pthread_cond_signal(&can_wait) != 0) {
        perror(error_cond_wait);
    }
    if (pthread_mutex_unlock(&mutex) != 0) {
        perror(error_mutex_unlock);
    }
    if (pthread_join(waitChild, NULL) != 0) {
        perror(error_thread_join);
    }
    lst_print(l);
    lst_destroy(l);
    while(remove_terminal(terminals)!= -1){

    }
    if (pthread_cond_destroy(&can_wait) != 0) {
        perror(error_cond_destroy_wait);
    }
    if (pthread_cond_destroy(&can_execute) != 0) {
        perror(error_cond_destroy_execute);
    }
    exit(EXIT_SUCCESS);
	return 0;
}
Пример #5
0
int main(int argc, char **argv) {
  pid_t child_pid; /* child process id */
  pthread_t monitor_thread; /* monitor thread */
  char *args[CMD_ARGS_MAX+1], buffer_cmd[LINE_COMMAND_MAX]; /* cmd related */
  char buffer_log[LINE_LOGFILE_MAX]; /* log related */

  if((g_lst_children = lst_new()) == NULL) {
    if(fprintf(stderr, "lst_new: couldn't create list\n") < 0)
      handle_error("fprintf");
    exit(EXIT_FAILURE);
  }

  g_log_file = f_open(PATH_LOGFILE_STR, "a+");

  while(!feof(g_log_file)) {
    f_gets(buffer_log, LINE_LOGFILE_MAX, g_log_file); /* NULL or iteracao # */
    if(feof(g_log_file)) break;
    if(sscanf(buffer_log, "%*s %d", &g_iterations) != 1)
      handle_error("sscanf");
    
    f_gets(buffer_log, LINE_LOGFILE_MAX, g_log_file); /* PID: # time: # s */
    f_gets(buffer_log, LINE_LOGFILE_MAX, g_log_file); /* total time: # s */
    if(sscanf(buffer_log, "%*[^0-9] %d", &g_total_time) != 1)
      handle_error("sscanf");
  }
  
  ++g_iterations;
  
  cond_init(&g_child_cv);
  cond_init(&g_monitoring_cv);
  mutex_init(&g_mutex);
  pcreate(&monitor_thread, process_monitor, NULL);
  
  while(true) {
    int numargs = readLineArguments(args,
      CMD_ARGS_MAX + 1, buffer_cmd, LINE_COMMAND_MAX);
    
    if(args[0] == NULL) continue;
    if(numargs < 0 || (numargs > 0 && !strcmp(args[0], COMMAND_EXIT_STR))) {
      
      mutex_lock(&g_mutex);
      g_monitoring = false;
      cond_signal(&g_monitoring_cv);
      mutex_unlock(&g_mutex);
      
      pjoin(monitor_thread);
      
      lst_print(g_lst_children);
      
      destroySharedResources();
      f_close(g_log_file);
      return EXIT_SUCCESS;
    }
    else {
      FILE *fp; /* To check file existance */
      if ((fp = fopen(args[0], "r")) == NULL)
        perror(args[0]);
      else {
        f_close(fp);
        
        mutex_lock(&g_mutex);
        while(g_num_children == MAXPAR)
          cond_wait(&g_child_cv, &g_mutex);
        mutex_unlock(&g_mutex);
        
        if((child_pid = fork()) < 0) perror("fork");
        else if(child_pid == 0) {
          execv(args[0],args);
          
          destroySharedResources();
          handle_error("execv");
        }
        else {
          mutex_lock(&g_mutex);
          if(insert_new_process(g_lst_children, child_pid, time(NULL)) != 0) {
            fprintf(stderr,
              "insert_new_process: failed to insert new process\n");
            exit(EXIT_FAILURE);
          }
          ++g_num_children;
          
          cond_signal(&g_monitoring_cv);
          mutex_unlock(&g_mutex);
        }
      }
    }
  }
}