【linux】——一个小程序
利用工作之余为小伙伴写了份作业,关于进程间通信的。题目如下:
父进程从键盘上接受1000个数据,对其求和sum1,子进程对这1000个数平方和sum2,结果传给父进程,父进程将sum1+sum2后,打印结果。 要求:用大小为10的共享区传递1000个数据;子进程用消息机制将sum2传给父进程。 |
主要利用共享内存实现进程间通信,使用管道实现进程间竞争关系,FreeBSD下测试通过。代码如下:时间有限,有可能有些不足,希望高手给予指点。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <sys/shm.h> 5 #include <signal.h> 6 7 const int key = 0x12345678; 8 static int pfd1[2], pfd2[2]; 9 10 #define SHM_LEN (10*1024) 11 #define VAL_NUM 5 12 13 int init_shm() { 14 int shmid = -1; 15 16 shmid = shmget((key_t)key, SHM_LEN, 0666 | IPC_CREAT); 17 if (shmid < 0) { 18 printf("shmget failed!\n"); 19 exit(-1); 20 } 21 22 return shmid; 23 } 24 25 void cancel_shm(int shmid) { 26 if (shmctl(shmid, IPC_RMID, 0) == -1) { 27 printf("shmctl failed!\n"); 28 exit(-1); 29 } 30 printf("cancel_shm successfully!\n"); 31 } 32 33 void *shm_get(int shmid) { 34 void *mem = NULL; 35 36 mem = shmat(shmid, 0, 0); 37 if (mem == (void *)-1) { 38 printf("shmat failed!\n"); 39 exit(-1); 40 } 41 42 return mem; 43 } 44 45 int get_val(int *val, int num) { 46 int i; 47 for (i = 0; i < num; i++) { 48 printf("please input a num:"); 49 scanf("%d", val + i); 50 } 51 } 52 void show_val (int *val, int num) { 53 int i; 54 for (i = 0; i < num; i++) { 55 printf("%d\t", *(val + i)); 56 } 57 printf("\n"); 58 } 59 60 int add_val (int *val, int num) { 61 int result = 0; 62 int i; 63 64 for (i = 0; i < num; i++) { 65 result += *(val + i); 66 } 67 68 return result; 69 } 70 71 int square_val (int *val, int num) { 72 int result = 0; 73 int i, tmp; 74 75 for (i = 0; i < num; i++) { 76 tmp = *(val + i); 77 result += (tmp * tmp); 78 } 79 80 return result; 81 } 82 83 void TELL_WAIT (void) { 84 if (pipe(pfd1) < 0 || pipe(pfd2) < 0) { 85 printf("pipe error!\n"); 86 exit(-1); 87 } 88 } 89 90 void TELL_PARENT (pid_t pid) { 91 if (write(pfd2[1], "c", 1) != 1) { 92 printf("write error!\n"); 93 exit(-1); 94 } 95 } 96 97 void WAIT_PARENT (void) { 98 char c; 99 100 if (read(pfd1[0], &c, 1) != 1) { 101 printf("read error!\n"); 102 exit(-1); 103 } 104 } 105 106 void TELL_CHILD (pid_t pid) { 107 if (write(pfd1[1], "p", 1) != 1) { 108 printf("write error!\n"); 109 exit(-1); 110 } 111 } 112 113 void WAIT_CHILD (void) { 114 char c; 115 116 if (read(pfd2[0], &c, 1) != 1) { 117 printf("read error!\n"); 118 exit(-1); 119 } 120 } 121 122 int main(int argc, char *argv[]) { 123 void *mem = NULL; 124 int shmid = -1; 125 pid_t pid = -1; 126 int val[VAL_NUM]; 127 int result = 0; 128 129 shmid = init_shm(); 130 131 TELL_WAIT(); 132 if ((pid = fork()) < 0) { //error 133 printf("fork error!\n"); 134 exit(-1); 135 } else if (pid == 0) { //child 136 int result = 0; 137 138 WAIT_PARENT(); 139 140 mem = shm_get(shmid); //get share memery 141 142 memcpy(val, mem, sizeof(int) * VAL_NUM); 143 result = square_val(val, VAL_NUM); 144 145 *(int *)((void *)mem + SHM_LEN - 4) = result; 146 147 TELL_PARENT(pid); 148 149 exit(1); 150 } else { //parent 151 int child_result = 0; 152 153 mem = shm_get(shmid); //get share memery 154 get_val(val, VAL_NUM); //get user input 155 memcpy(mem, val, sizeof(int) * VAL_NUM); //copy user input to share memery 156 157 TELL_CHILD(pid); 158 159 result = add_val(val, VAL_NUM); 160 161 WAIT_CHILD(); 162 child_result = *(int *)((void *)mem + SHM_LEN - 4); 163 printf("result:%d, child_result:%d, all:%d\n", result, child_result, result + child_result); 164 } 165 166 cancel_shm(shmid); 167 168 return 0; 169 }