• 进程间通信:用信号量实现对共享内存读写顺序的控制


    这本是一道题:一本是一个全局变量来做的控制共享内存通信方式,一个已经实现的信号量通信,最终的结果是让这两个掺和在一起。用信号量来控制共享内存通信的读写顺序。

                原本信号量通信方式的函数在这是,原本的共享内存程序在这里。

                做的最新的结果是可以通信了,但是在客户端有一点点异常,就是在服务器端还没有释放信号量,但是客户端不可以获取的,这使我很疑惑。

    服务器端:

    1. #include <unistd.h>   
    2. #include <stdlib.h>   
    3. #include <stdio.h>   
    4. #include <string.h>   
    5. #include <sys/types.h>   
    6. #include <sys/ipc.h>   
    7. #include <sys/shm.h>   
    8. #include "shm_com.h"   
    9.   
    10. #include <sys/sem.h>   
    11.   
    12. #include <signal.h>   
    13. /********************************************************/  
    14. int pid,semid;  
    15. /********************************************************/  
    16.   
    17. void my_func(int sign_no)  
    18. {  
    19.     if(sign_no==SIGINT)  
    20.     {  
    21.         printf("\nYes Sir,I have get SIGINT\n");  
    22.         if(semctl(semid, 0, IPC_RMID, 0)<0)  
    23.         {  
    24.             printf("semctl remove semaphore set failed\n");  
    25.             exit(EXIT_FAILURE);  
    26.         }  
    27.         printf("semctl remove semaphore set OK\n");  
    28.         exit(EXIT_FAILURE);  
    29.     }  
    30. }  
    31.   
    32. int main(void)  
    33. {  
    34.     int running=1;  
    35.     void *shared_memory=(void *)0;  
    36.     struct shared_use_st *shared_stuff;  
    37.     char buffer[BUFSIZ];  
    38.     int shmid;  
    39.   
    40.     signal(SIGINT, my_func);  
    41.   
    42. /***************************************************************/     
    43.       
    44.     key_t semkey;  
    45.     if((semkey=ftok("/home", 1))<0)  
    46.     {  
    47.         printf("ftok failed\n");  
    48.         exit(EXIT_FAILURE);  
    49.     }  
    50.     printf("ftok ok, semkey=%d\n", semkey);  
    51.       
    52.     if((semid=semget(semkey, 1, IPC_CREAT|0666))<0)  
    53.     {  
    54.         printf("semget failed\n");  
    55.         exit(EXIT_FAILURE);  
    56.     }  
    57.     printf("semget ok, semid = %d\n", semid);  
    58.       
    59.     if((semctl(semid, 0, SETVAL, 1))<0)  
    60.     {  
    61.         printf("semctl set sermval failed\n");  
    62.         exit(EXIT_FAILURE);  
    63.     }  
    64.     printf("semctl set semval ok\n");  
    65.       
    66.     struct sembuf p_op_buf, v_op_buf;  
    67.     p_op_buf.sem_num=0;  
    68.     p_op_buf.sem_op = -1;  
    69.       
    70. /******************************************************************/  
    71.   
    72.     /*创建共享内存*/  
    73.     shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);  
    74.     if(shmid==-1)  
    75.     {  
    76.         fprintf(stderr,"shmget failed\n");  
    77.         exit(EXIT_FAILURE);  
    78.     }  
    79.   
    80.     /*映射共享内存*/  
    81.     shared_memory=shmat(shmid,(void *)0,0);  
    82.     if(shared_memory==(void *)-1)  
    83.     {  
    84.         fprintf(stderr,"shmat failed\n");  
    85.         exit(EXIT_FAILURE);  
    86.     }  
    87.     printf("Memory attached at %X\n",(int)shared_memory);  
    88.   
    89.     /*让结构体指针指向这块共享内存*/  
    90.     shared_stuff=(struct shared_use_st *)shared_memory;  
    91.   
    92.     /*循环的向共享内存中写数据,直到写入的为“end”为止*/  
    93.     while(running)  
    94.     {  
    95. /******************************************************************************/  
    96.         //获取信号量   
    97.         if(semop(semid, &p_op_buf, 1)<0)  
    98.         {  
    99.         printf("semop failed\n");  
    100.         exit(EXIT_FAILURE);  
    101.         }  
    102.         printf("shm2 get the semaphore\n");  
    103. /******************************************************************************/  
    104.           
    105.         printf("Ener some text:");  
    106.         fgets(buffer,BUFSIZ,stdin);  
    107.         strncpy(shared_stuff->some_text,buffer,TEXT_SZ);  
    108.         shared_stuff->written_by_you=1;  
    109.         if(strncmp(buffer,"end",3)==0)  
    110.         {  
    111.             running=0;  //结束循环   
    112.         }  
    113.   
    114. /*****************************************************************************/  
    115.         //释放信号量   
    116.         v_op_buf.sem_num = 0;  
    117.         v_op_buf.sem_op = 1;  
    118.         v_op_buf.sem_flg = 0;  
    119.         if(semop(semid, &v_op_buf, 1)<0)  
    120.         {  
    121.             printf("semop release semaphore failed\n");  
    122.             exit(EXIT_FAILURE);  
    123.         }  
    124.         printf("semop release semaphore ok\n");  
    125. /*****************************************************************************/  
    126.     }  
    127.   
    128.     /*删除共享内存*/  
    129.     if(shmdt(shared_memory)==-1)  
    130.     {  
    131.         fprintf(stderr,"shmdt failed\n");  
    132.         exit(EXIT_FAILURE);  
    133.     }  
    134.     exit(EXIT_SUCCESS);  
    135. }  

    客户端:

    1. #include <unistd.h>   
    2. #include <stdlib.h>   
    3. #include <stdio.h>   
    4. #include <string.h>   
    5. #include <sys/types.h>   
    6. #include <sys/ipc.h>   
    7. #include <sys/shm.h>   
    8. #include "shm_com.h"   
    9.   
    10. #include <sys/sem.h>   
    11.   
    12. int main(void)  
    13. {  
    14.     int running=1;  
    15.     void *shared_memory=(void *)0;  
    16.     struct shared_use_st *shared_stuff;  
    17.     int shmid;  
    18. /***************************************************************/     
    19.     int pid,semid;  
    20.     key_t semkey;  
    21.     if((semkey=ftok("/home", 1))<0)  
    22.     {  
    23.         printf("ftok failed\n");  
    24.         exit(EXIT_FAILURE);  
    25.     }  
    26.     printf("ftok ok, semkey=%d\n", semkey);  
    27.       
    28.     if((semid=semget(semkey, 0, 0))<0)  
    29.     {  
    30.         printf("semget failed\n");  
    31.         exit(EXIT_FAILURE);  
    32.     }  
    33.     printf("semget ok, semid = %d\n", semid);  
    34.       
    35.     if((semctl(semid, 0, SETVAL, 1))<0)  
    36.     {  
    37.         printf("semctl set sermval failed\n");  
    38.         exit(EXIT_FAILURE);  
    39.     }  
    40.     printf("semctl set semval ok\n");  
    41.       
    42.     struct sembuf p_op_buf, v_op_buf;  
    43.     p_op_buf.sem_num=0;  
    44.     p_op_buf.sem_op = -1;  
    45.     p_op_buf.sem_flg = 0;  
    46.       
    47. /******************************************************************/  
    48.     /*创建共享内存*/  
    49.     shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);  
    50.     if(shmid==-1)  
    51.     {  
    52.         fprintf(stderr,"shmget failed\n");  
    53.         exit(EXIT_FAILURE);  
    54.     }  
    55.   
    56.     /*映射共享内存*/  
    57.     shared_memory=shmat(shmid,(void *)0,0);  
    58.     if(shared_memory==(void *)-1)  
    59.     {  
    60.         fprintf(stderr,"shmat failed\n");  
    61.         exit(EXIT_FAILURE);  
    62.     }  
    63.     printf("Memory attached at %X\n",(int)shared_memory);  
    64.   
    65.     /*让结构体指针指向这块共享内存*/  
    66.     shared_stuff=(struct shared_use_st *)shared_memory;  
    67.   
    68.     /*控制读写顺序*/  
    69.     //shared_stuff->written_by_you=0;   
    70.   
    71.     /*循环的从共享内存中读数据,直到读到“end”为止*/  
    72.     while(running)  
    73.     {  
    74. /* 
    75.        if(shared_stuff->written_by_you) 
    76.        { 
    77.          printf("You wrote:%s",shared_stuff->some_text); 
    78.            sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写 
    79.            shared_stuff->written_by_you=0; 
    80.            if(strncmp(shared_stuff->some_text,"end",3)==0) 
    81.            { 
    82.                running=0; //结束循环 
    83.            } 
    84.        } 
    85. */  
    86. /******************************************************************************/  
    87.         //获取信号量   
    88.         if(semop(semid, &p_op_buf, 1)<0)  
    89.         {  
    90.         printf("semop failed\n");  
    91.         exit(EXIT_FAILURE);  
    92.         }  
    93.         printf("shm1 get the semaphore\n");  
    94. /*******************************************************************************/  
    95.   
    96.         printf("You wrote:%s",shared_stuff->some_text);  
    97.         sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写   
    98.   
    99.         if(strncmp(shared_stuff->some_text,"end",3)==0)  
    100.         {  
    101.            running=0; //结束循环   
    102.         }  
    103.           
    104. /****************************************************************************/        
    105.         //释放信号量   
    106.         v_op_buf.sem_num = 0;  
    107.         v_op_buf.sem_op = 1;  
    108.         v_op_buf.sem_flg = 0;  
    109.         if(semop(semid, &v_op_buf, 1)<0)  
    110.         {  
    111.             printf("semop release semaphore failed\n");  
    112.             exit(EXIT_FAILURE);  
    113.         }  
    114.         printf("semop release semaphore ok\n");  
    115. /*****************************************************************************/  
    116.          
    117.     }  
    118. /*******************************************************************************/  
    119.   
    120.     /*删除共享内存*/  
    121.     if(shmdt(shared_memory)==-1)  
    122.     {  
    123.         fprintf(stderr,"shmdt failed\n");  
    124.         exit(EXIT_FAILURE);  
    125.     }  
    126.   exit(EXIT_SUCCESS);  
    127. }  
    以后的解决方案是先把那个信号量的程序由一个程序拆分成两个,彻底掌握信号量通信的过程。再来改造共享内存读写顺序。课程还要继续有机会再来解决吧!还一个实现上边 的方法参考这里



  • 相关阅读:
    js的浅拷贝与深拷贝
    用Nodejs连接MySQL(原文链接)
    HTML5交互性图表库
    GitHub Desktop离线安装包
    docker--Dockerfile--sonarqube
    docker --Nexus仓库
    docker --Dockerfile--一些语法
    zookeeper 四字命令
    docker --swarm创建一个集群
    docker --swarm启动2375端口监听
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6332962.html
Copyright © 2020-2023  润新知