2016-10-28,14:53,Fri編程
題目:c編程---在終端輸入(Num,Cmd),Num表明隊員號,Cmd表明命令。Cmd爲1,奔跑; Cmd爲2,顯示已奔跑時間(精確到ms); Cmd爲3,中止奔跑並顯示全部隊員的狀態(狀態0:未奔跑; 狀態1:正在奔跑; 狀態2:奔跑過但已中止)。併發
單進程:每一個隊員匹配一個信息結構體:Struct{int num;int cmd;int time;int status};使用switch(msg[num].cmd) 執行對應操做來改變 msg[num].time和msg[num.]status便可。 ide
多進程:每一個隊員匹配一個進程。子進程睡眠態-->狀態1,運行態-->狀態2,暫停態-->狀態3. 而進程間通訊咱們選用消息隊列和信號的方法:函數
子進程被建立以後,因msgrcv()而處於阻塞態(即睡眠態)。接收到特定msg,便進入運行態while(1)。接收SIGUSR1信號時,將運行時間發送給父進程。接收到SIGSTOP信號時進入暫停態,且父進程中獲取各子程序的狀態。spa
1 #include "head.h" 2 3 struct { 4 long mtype; 5 int mcmd; 6 clock_t mtv; 7 }msg; 8 pid_t pid[6]; 9 int fd[6]; 10 key_t key; 11 char dir[64]; 12 char * p; 13 int msqid, i, num, cmd, status; 14 15 void send_running_time(int arg); //得到運行時間併發送 16 void recv_running_time(); 17 void recycle_child(int arg); //殺死各子進程並回收資源 18 void get_fds(); 19 void get_status(); //獲取子進程狀態 20 21 int main(int argc, const char *argv[]) 22 { 23 key = ftok(".", 345); 24 if(key < 0){ 25 perror("ftok failed"); 26 return -errno; 27 } 28 29 msqid = msgget(key, IPC_CREAT|IPC_EXCL|0664); 30 if(msqid <= 0){ 31 if(errno == EEXIST){ 32 msqid = msgget(key, 0664); 33 }else{ 34 perror("msgget failed\n"); 35 return -errno; 36 } 37 } 38 39 for(i = 1; i < 6; i++){ 40 pid[i] = fork(); 41 if(pid[i] < 0){ 42 perror("fork failed\n"); 43 return -errno; 44 }else if(pid[i] == 0){ 45 msgrcv(msqid, &msg, sizeof(msg), i, 0); 46 signal(SIGUSR1, send_running_time); 47 while(1); 48 }else 49 ; 50 } 51 52 signal(SIGINT, recycle_child); 53 while(1){ 54 get_fds(); 55 printf("*******Num && cmd*********\n"); 56 scanf("%d,%d",&num, &cmd); 57 msg.mtype = num; 58 msg.mcmd = cmd; 59 switch(cmd){ 60 case 1: 61 msgsnd(msqid, &msg, sizeof(msg), 0); 62 printf("No.%d is start off running!\n", num); 63 break; 64 case 2: 65 kill(pid[num], SIGUSR1); 66 recv_running_time(); 67 break; 68 case 3: 69 kill(pid[num], SIGTSTP); 70 sleep(1); 71 get_status(); 72 break; 73 default: 74 perror("invalid cmd"); 75 break; 76 } 77 } 78 return 0; 79 }
1 void send_running_time(int arg) 2 { 3 msg.mtv = clock(); 4 msgsnd(msqid, &msg, sizeof(msg), 0); 5 } 6 7 void recv_running_time() 8 { 9 msgrcv(msqid, &msg, sizeof(msg), num, 0); 10 printf("No.%ld has run %ld ms\n",msg.mtype, msg.mtv/1000); 11 } 12 13 void recycle_child(int arg) 14 { 15 for(i = 1; i < 6; i++){ 16 kill(SIGKILL, pid[i]); 17 waitpid(pid[i], &status, WNOHANG ); 18 } 19 exit(0); 20 } 21 22 void get_fds() 23 { 24 for(i = 1; i < 6; i++){ 25 sprintf(dir,"/proc/%d/status",pid[i]); 26 fd[i] = open(dir,O_RDONLY); 27 } 28 } 29 30 void get_status() 31 { 32 for(i = 1; i < 6; i++){ 33 read(fd[i], dir, sizeof(dir)); 34 p = strtok(dir, "\n"); 35 p = strtok(NULL, "\n"); 36 printf("No.%d\t%s\n",i, p); 37 } 38 }
TIPS: code