使用共享实现两个进程之间的聊天-使用有名信号量实现同步
1.共享内存,它是LINUX下,属于SYSTEM V IPC对象的一种通信方式。 1)共享内存是一种尤为高效的进程间通信方式,进程直接进行读写操作,不需要任何数据的COPY。 2)内核中专门留出了一块内存区,进程间交互信息时,只需要将其映射到自己的私有地址空间。 3)进程之间由于是共享内存,因此也需要一种同步机制,如信号量,和互斥锁等。 2.创建一个共享内存的
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;
}
最后,这里需要打开两个终端,去运行对应的进程,就可以实现不同进程间聊天了,博主有的地方写的不好,还请海涵。
更多推荐
所有评论(0)