#c #exec #fork
#c #exec #форк
Вопрос:
У меня возникли проблемы с моей программой, я хочу, чтобы моя функция run_uptime отображала выходные данные функции uptime каждые 5 секунд в stdout. Тем не менее, я не знаю, что я делаю неправильно в своем коде, я просмотрел различные другие вопросы, связанные с exec() и fork(), но, похоже, я все еще не могу найти решение. Еще одна вещь, как я могу переписать вызов fork без оператора switch , но это скорее эстетическая причина, но я все равно хочу знать, как это сделать. Я был бы признателен за любую помощь. Пожалуйста, объясните, почему, потому что я новичок.
Постановка проблемы, что должна делать программа:
Вы должны создать программу, которая выполняет следующее:
o При запуске считайте общее время выполнения (в секундах), в течение которого пользователь хочет запустить программу. Значение по умолчанию 10 секунд будет использоваться, если пользователь не указывает время при запуске программы (т.Е. rohan> a3 30 заставляет программу работать в течение 30 секунд, rohan> a3 вы бы запустили программу в течение 10 секунд).
o Программа должна создать три дочерних процесса, затем busy-подождите, пока все дочерние процессы не будут завершены, а затем завершите работу.
o Первый дочерний процесс должен реализовать часы, которые печатают час, минуту и секунду раз в секунду (в удобочитаемом локальном времени)
o Второй дочерний процесс должен запускать программу времени безотказной работы (/usr/bin/ uptime) каждые 5 секунд
o Третий дочерний процесс должен реализовать таймер обратного отсчета, который печатает оставшиеся минуты и секунды раз в секунду до достижения 00:00.
o Третий дочерний процесс, по достижении 00:00, должен уведомить (сигнализировать, или передавать, или … и т. Д., Ваш выбор механизма IPC) первый и второй дочерние процессы ’ (т. Е. Это процессы-братья), сообщающие им о завершении, а затем завершают себя.
o После завершения всех дочерних процессов родительский должен напечатать дружественное сообщение, а затем выйти.
Вот мой код, он компилируется, но мне нужен другой вывод.
/* Include Files */
#include <stdio.h>
#include <time.h> /* for local time functions */
#include <unistd.h> /* for fork */
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h> /* for wait function */
#include <sys/types.h> /* for pid_t */
/* remember 0 means program finished correctly, by unix convention */
/* Definitions */
#define TIME_QUANTUM 5 //Default time for program to run!
/* Functions */
void system_clock(void); //function to display human readable time.
void time_to_kill(int timequota); //prints out the time in a countdown fashion, till program ends.
void run_uptime(void);
/* Variables */
int procpipe1[2]; //Allocate Pipe Set 1
int procpipe2[2]; //Allocate Pipe Set 2
char bufkill[12]; //Buffer to hold kill signal, to tell other processes to end.
int main(int argc, const char * argv[])
{
int time=TIME_QUANTUM;
if(argc==2)
{
time=atoi(argv[1]); //looking to see if user wants a custom running time.
}
//Creating pipes before creating child processes, so they could communicate.
pipe(procpipe1);
pipe(procpipe2);
printf("Pipes opened, now creating child process!n");
//Create Child Processes and run associated functions in them.
//Creating the the 1st child process!
switch (fork())
{
case -1:
printf("Error: couldn't create 1st Child!n");
exit(1);
case 0: //If no error in creating child process then create process!
printf("nChild 1 process: time_to_kill executing...n");
system_clock();
exit(1);
default:
break;
}
//Creating the 2nd child process!
switch (fork())
{
case -1:
printf("Error: couldn't create 3rd Child!n");
case 0: //If no error in creating child process then create process!
printf("nChild 2 process: time_to_kill executing...n");
run_uptime();
exit(1);
default:
break;
}
//Creating the 3rd child process!
switch (fork())
{
case -1:
printf("Error: couldn't create 2nd Child!n");
exit(1);
case 0: //If no error in creating child process then create process!
printf("nChild 3 process: time_to_kill executing...n");
time_to_kill(time);
exit(1);
default:
break;
}
printf("Parent closing pipesn");
//Need to close the pipes after using them, close communications between processes.
//pipe close error checking
close(procpipe1[0]);
close(procpipe1[1]);
close(procpipe2[0]);
close(procpipe1[1]);
printf("Parent waiting for children completion...n");
//Wait for child processes to end before ending Main, the overall process
//that spawned the child processes.
wait(NULL);
wait(NULL);
wait(NULL);
printf("Time to print out a Friendly Message!n");
printf("Parent process finishing, bye!n");
exit(EXIT_SUCCESS);
}//end main
//This is the 1st Child Process
void system_clock(void)
{
/* variable of system_clock()*/
//temp buffer to get termination string
char str1[12];
time_t now;
struct tm *lcltime;
strcpy(str1, "time to die"); //store this string into str1 local variable
close(procpipe1[0]);
close(procpipe1[1]);
close(procpipe2[1]);
//show current time
for(;;)
{
now = time ( NULL );
lcltime = localtime ( amp;now );
//read message from child 2 process
int status = read(procpipe2[0], bufkill, 12);
if ((strcmp(str1, bufkill)) != 0)
{
//printf("Read status: %d, Buffer= %sn", status, bufkill);
printf ("The time is %d:%d:%dn", lcltime->tm_hour, lcltime->tm_min, lcltime->tm_sec );
//show ever second
sleep(1);
}
//if end signal came in
//if(ret == 0)
if ((strcmp(str1, bufkill)) == 0)
{
//close reading end
close(procpipe2[0]);
//return back to parent
printf("Child 1 process: system_clock ending...n");
exit(1);
}
}
}//end system_clock
//This is the 2nd Child Process
void run_uptime()
{
// variable of run_uptime
//temp buffer to get termination string
char str1[12];
strcpy(str1, "time to die"); //store this string into str1 local variable
close(procpipe1[0]);
close(procpipe1[1]);
close(procpipe2[1]);
for(;;)
{
//read message from child 2 process
int status = read(procpipe2[0], bufkill, 12);
if ((strcmp(str1, bufkill)) != 0)
{
//printf("Read status: %d, Buffer= %sn", status, bufkill);
execl("/usr/bin/uptime","uptime",NULL);
//show ever 5 seconds
sleep(1);
}
//if end signal came in
if ((strcmp(str1, bufkill)) == 0)
{
//close reading end of pipe.
close(procpipe2[0]);
//return back to parent
printf("Child 2 process: run_uptime ending...n");
exit(1);
}
}
}//end run_uptime
//This is the 3rd Child Process
void time_to_kill(int timequota) //This process signals the other processes to stop.
{
/* Need to change this signal */
//string signal to end process
strcpy(bufkill, "time to die");
//Pipes that aren't being used close them.
close(procpipe1[0]);
close(procpipe1[1]);
close(procpipe2[0]);
for( ;timequota>0; timequota--)
{
printf("Count Down: 00:0%dn", timequota);
//send signal to child 1 process and child 2 process not to end
write(procpipe2[1], "not die yet",12); //write into pipe2 statement that doesn't signal stopping process.
//count down every second
sleep(1);
}
//send signal to child 1 process and child 2 process to be terminate itself.
write(procpipe2[1], bufkill, sizeof(bufkill)); //write into pipe2 the kill statement stored in bufkill
//close pipe 2 writing end
close(procpipe2[1]);
//back to main
printf("Count Down: 0n");
printf("Child 3 process: time_to_kill ending...n");
exit(1);
}//end time_to_kill
Комментарии:
1. Из кода, который вы показываете, вы не хотите
exec*()
, ноsystem()
илиpopen()
илиposix_spawn()
, если доступно.exec*()
Функции не возвращаются. Возможно, вам захочется внимательно прочитатьman 3 exec
.2. Я добавил в свой вопрос формулировку проблемы и то, что должна делать моя программа.
3. Мне не разрешено использовать system, и мне разрешено использовать только exec() и его производные.
4. При обработке ошибок для второго форка пропускается «выход». «man wait» не говорит, что «wait (NULL)» разрешено. execl в thread2 заменит дочерний процесс программой времени безотказной работы, поэтому вашего run_uptime больше не будет. Ваши три функции никогда не возвращаются, поэтому нет необходимости завершать () после них. Если вы получаете сигнал во время чтения, может быть прочитана только часть сообщения, и вы не распознаете сообщение правильно.
5. Я предложил альтернативы
exec*()
в своем первом комментарии.