1.共享内存,它是LINUX下,属于SYSTEM V IPC对象的一种通信方式。
  1)共享内存是一种尤为高效的进程间通信方式,进程直接进行读写操作,不需要任何数据的COPY。
  2)内核中专门留出了一块内存区,进程间交互信息时,只需要将其映射到自己的私有地址空间。
      3)进程之间由于是共享内存,因此也需要一种同步机制,如信号量,和互斥锁等。
  2.创建一个共享内存的步骤
    1) 创建或打开共享内存(对应的函数 shmget)
    2)映射共享内存(对应的函数shmat)
    3)撤销共享内存(对应得函数shmdt)
    4)删除共享内存对象(shmctl)
对应的头文件和相关参数可在linux下使用man 手册查询,这里不再一一赘述。
  3.有名信号量的创建的步骤
     1)创建有名信号量(sem_open函数),在这里说一下这个函数
    
sem_t *sem_open(const char *name, int oflag,
mode_t mode, unsigned int value);
         name 是创建有名信号量的名称,其保存在/dev/shm目录下。
         mode 为参数指定权限位。一般默认为0666
        oflag 为创建或读取文件 。参数可设置为O_CREAT等
        value 为有名信号量的初始值。
    2)其次就是对其进行PV操作和无名信号量相同(P操作sem_wait;V操作sem_post)
    3)关闭有名信号量(sem_close)
   4)删除有名信号量(sem_unlink)
   注意:这里倘若使用有名信号量实现程序同步时,第一次实现正常时,第二次出现死循环时,可能就是因为没有关闭和删除有名信号量的问题。
   最后就是实现我们不同进程间的聊天了。
   4 首先,第一个进程先进行说话,由第二个进程接收,再去进行说话,以此类推,直到双方不想聊天为止,这里代码,我们使用#号代表聊天结束。
   下面是process-chat1.c代码
  

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
    //创建有名信号量
    sem_t * sem1 = sem_open("xld1",O_CREAT | O_RDONLY,0666, 1);
     if(SEM_FAILED == sem1)
    {
      perror("sem_open1 error");
      return -1;
    }
    sem_t * sem2 = sem_open("xld2",O_CREAT | O_RDONLY, 0666, 0);
     if(SEM_FAILED == sem2)
    {
      perror("sem_open2 error");
      return -1;
    }
     //创建共享内存
     key_t key =ftok(".",12);
     if(key<0)
     {
       perror("ftok error");
       return -1;
     }
      int ret = shmget(key,1024,IPC_CREAT | 0666);
      if(ret<0)
      {
        perror("shmget error");
        return -1;
      }
        char *p = shmat(ret,NULL,0);
        if((char *)-1 == p)
        {
         perror("shmat error");
         return -1;
        }

          while(1)
            {
            sem_wait(sem1);
            if(*p != 0)
            {
               printf("from 库里:%s\n",p);
            }
            memset(p,0,1024);
            printf("詹姆斯:");
            gets(p);
            //strcpy(p,buf);

            if(strcmp(p,"#")==0)
            {
               sem_post(sem2);
               break;
            }
            //printf("%s\n",p);
            sem_post(sem2);
            }
         shmdt(p);
      sem_close(sem1);
      sem_close(sem2);

      sem_unlink("xld1");
      sem_unlink("xld2");
     return 0;
}

接下来是另一个进程process-chat2.c的代码:

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
    //创建有名信号量
    sem_t * sem1 = sem_open("xld1",O_CREAT | O_RDONLY,0666, 1);
     if(SEM_FAILED == sem1)
    {
      perror("sem_open1 error");
      return -1;
    }
    sem_t * sem2 = sem_open("xld2",O_CREAT | O_RDONLY, 0666, 0);
     if(SEM_FAILED == sem2)
    {
      perror("sem_open2 error");
      return -1;
    }
     key_t key =ftok(".",12);
     if(key<0)
     {
       perror("ftok error");
       return -1;
     }
      int ret = shmget(key,1024,IPC_CREAT | 0666);
      if(ret<0)
      {
        perror("shmget error");
        return -1;
      }
        char *p = shmat(ret,NULL,0);
        if((char *)-1 == p)
        {
         perror("shmat error");
         return -1;
        }
         while(1)
         {
            sem_wait(sem2);
            //char buf[1024];
            //memset(buf,0,sizeof(buf));
            if(*p!=0)
            {
              printf("from 詹姆斯:%s\n",p);
            }
            memset(p,0,1024);
            printf("库里:");
            gets(p);
            //printf("库里:%s",p);

            if(strcmp(p,"#")==0)
            {
               sem_post(sem1);
               break;
            }
            //strcpy(p,buf);
            sem_post(sem1);
         }
         shmdt(p);


      sem_close(sem1);
      sem_close(sem2);

      sem_unlink("xld1");
      sem_unlink("xld2");
     shmctl(ret,IPC_RMID,NULL);
     return 0;
}

最后,这里需要打开两个终端,去运行对应的进程,就可以实现不同进程间聊天了,博主有的地方写的不好,还请海涵。

Logo

更多推荐