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

来源:互联网 发布:国外类似淘宝网站 编辑:程序博客网 时间:2024/06/05 04:09

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

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

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

服务器端:

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include "shm_com.h"#include <sys/sem.h>#include <signal.h>/********************************************************/int pid,semid;/********************************************************/void my_func(int sign_no){if(sign_no==SIGINT){printf("\nYes Sir,I have get SIGINT\n");if(semctl(semid, 0, IPC_RMID, 0)<0){printf("semctl remove semaphore set failed\n");exit(EXIT_FAILURE);}printf("semctl remove semaphore set OK\n");exit(EXIT_FAILURE);}}int main(void){    int running=1;void *shared_memory=(void *)0;struct shared_use_st *shared_stuff;char buffer[BUFSIZ];int shmid;signal(SIGINT, my_func);/***************************************************************/key_t semkey;if((semkey=ftok("/home", 1))<0){printf("ftok failed\n");exit(EXIT_FAILURE);}printf("ftok ok, semkey=%d\n", semkey);if((semid=semget(semkey, 1, IPC_CREAT|0666))<0){printf("semget failed\n");exit(EXIT_FAILURE);}printf("semget ok, semid = %d\n", semid);if((semctl(semid, 0, SETVAL, 1))<0){printf("semctl set sermval failed\n");exit(EXIT_FAILURE);}printf("semctl set semval ok\n");struct sembuf p_op_buf, v_op_buf;p_op_buf.sem_num=0;p_op_buf.sem_op = -1;/******************************************************************//*创建共享内存*/shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);if(shmid==-1){    fprintf(stderr,"shmget failed\n");exit(EXIT_FAILURE);}/*映射共享内存*/shared_memory=shmat(shmid,(void *)0,0);if(shared_memory==(void *)-1){    fprintf(stderr,"shmat failed\n");exit(EXIT_FAILURE);}printf("Memory attached at %X\n",(int)shared_memory);/*让结构体指针指向这块共享内存*/shared_stuff=(struct shared_use_st *)shared_memory;/*循环的向共享内存中写数据,直到写入的为“end”为止*/while(running){/******************************************************************************///获取信号量if(semop(semid, &p_op_buf, 1)<0){   printf("semop failed\n");   exit(EXIT_FAILURE);}printf("shm2 get the semaphore\n");/******************************************************************************/printf("Ener some text:");fgets(buffer,BUFSIZ,stdin);strncpy(shared_stuff->some_text,buffer,TEXT_SZ);shared_stuff->written_by_you=1;if(strncmp(buffer,"end",3)==0){    running=0;  //结束循环}/*****************************************************************************///释放信号量v_op_buf.sem_num = 0;v_op_buf.sem_op = 1;v_op_buf.sem_flg = 0;if(semop(semid, &v_op_buf, 1)<0){printf("semop release semaphore failed\n");exit(EXIT_FAILURE);}printf("semop release semaphore ok\n");/*****************************************************************************/}/*删除共享内存*/if(shmdt(shared_memory)==-1){    fprintf(stderr,"shmdt failed\n");exit(EXIT_FAILURE);}exit(EXIT_SUCCESS);}

客户端:

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include "shm_com.h"#include <sys/sem.h>int main(void){    int running=1;void *shared_memory=(void *)0;struct shared_use_st *shared_stuff;int shmid;/***************************************************************/int pid,semid;key_t semkey;if((semkey=ftok("/home", 1))<0){printf("ftok failed\n");exit(EXIT_FAILURE);}printf("ftok ok, semkey=%d\n", semkey);if((semid=semget(semkey, 0, 0))<0){printf("semget failed\n");exit(EXIT_FAILURE);}printf("semget ok, semid = %d\n", semid);if((semctl(semid, 0, SETVAL, 1))<0){printf("semctl set sermval failed\n");exit(EXIT_FAILURE);}printf("semctl set semval ok\n");struct sembuf p_op_buf, v_op_buf;p_op_buf.sem_num=0;p_op_buf.sem_op = -1;p_op_buf.sem_flg = 0;/******************************************************************//*创建共享内存*/shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);if(shmid==-1){    fprintf(stderr,"shmget failed\n");exit(EXIT_FAILURE);}/*映射共享内存*/shared_memory=shmat(shmid,(void *)0,0);if(shared_memory==(void *)-1){    fprintf(stderr,"shmat failed\n");exit(EXIT_FAILURE);}printf("Memory attached at %X\n",(int)shared_memory);/*让结构体指针指向这块共享内存*/shared_stuff=(struct shared_use_st *)shared_memory;/*控制读写顺序*///shared_stuff->written_by_you=0;/*循环的从共享内存中读数据,直到读到“end”为止*/while(running){/*   if(shared_stuff->written_by_you)   {     printf("You wrote:%s",shared_stuff->some_text);   sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写   shared_stuff->written_by_you=0;   if(strncmp(shared_stuff->some_text,"end",3)==0)   {       running=0; //结束循环   }   }*//******************************************************************************///获取信号量if(semop(semid, &p_op_buf, 1)<0){   printf("semop failed\n");   exit(EXIT_FAILURE);}printf("shm1 get the semaphore\n");/*******************************************************************************/printf("You wrote:%s",shared_stuff->some_text);sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写if(strncmp(shared_stuff->some_text,"end",3)==0){   running=0; //结束循环}/****************************************************************************///释放信号量v_op_buf.sem_num = 0;v_op_buf.sem_op = 1;v_op_buf.sem_flg = 0;if(semop(semid, &v_op_buf, 1)<0){printf("semop release semaphore failed\n");exit(EXIT_FAILURE);}printf("semop release semaphore ok\n");/*****************************************************************************/   }/*******************************************************************************//*删除共享内存*/if(shmdt(shared_memory)==-1){fprintf(stderr,"shmdt failed\n");exit(EXIT_FAILURE);}  exit(EXIT_SUCCESS);}
以后的解决方案是先把那个信号量的程序由一个程序拆分成两个,彻底掌握信号量通信的过程。再来改造共享内存读写顺序。课程还要继续有机会再来解决吧!还一个实现上边 的方法参考这里。




原创粉丝点击