【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!
");
 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!
");
 28         exit(-1);
 29     }   
 30     printf("cancel_shm successfully!
");
 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!
");
 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	", *(val + i));
 56     }
 57     printf("
");
 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!
");
 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!
");
 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!
");
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!
");
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!
");
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!
");    
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
", result, child_result, result + child_result);
164     }
165 
166     cancel_shm(shmid);
167 
168     return 0;
169 }
原文地址:https://www.cnblogs.com/ngnetboy/p/4915149.html