zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    并发容器和框架之ConcurrentHashMap
    Java的LockSupport工具,Condition接口和ConditionObject
    从源码来看ReentrantLock和ReentrantReadWriteLock
    VMWARE虚拟机上Terminal中使用sudo出现”** 不在sudoers文件中,此事将被警告 “错误
    mac下idea运行项目慢问题解决
    Idea 只修改编辑区主题
    redis内部数据结构的数据结构
    mysql存储过程详解
    HashMap中resize()剖析
    谈Redis的refash的增量式扩容
  • 原文地址:https://www.cnblogs.com/ngnetboy/p/4915149.html
Copyright © 2011-2022 走看看