使用共享内存和信号灯(同步机制)实现多进程间通信

环境:linux C

功能:使用共享内存和信号灯(同步机制)实现多进程间通信

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h> //信号signal头文件
#include <sys/types.h>//ftok()
#include <sys/ipc.h> //ipc对象头文件
#include <sys/shm.h> //共享内存头文件
#include <sys/sem.h>//信号灯机制头文件


#define N 64 //共享内存的大小
#define READ 0 //信号灯集合中信号量(读资源)编号
#define WRITE 1 //信号灯集合中信号量(写资源)编号


//信号灯初始化共用体定义
union semun
{
int val;
struct semid_ds * buf;
unsigned short * array;
struct seminfo * _buf;
};


//封装一个对信号灯所有信号量进行初始化函数
void init_sem(int semid, int s[],int n)
{
int i;
union semun myun;


for(i=0; i<n; i++)
{
myun.val = s[i];
semctl(semid, i, SETVAL, myun);
}


}


//封装一个信号灯某个信号量进行pv操作函数
void pv_sem(int semid, int num, int op)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = op;
buf.sem_flg = 0;
semop(semid,&buf,1);
}


int main()
{
int shmid;
int semid;
int s[] = {0,1};//信号灯内各信号量初值
pid_t pid;
key_t key;
char * shmaddr;


//创建key
if((key = ftok(".",'s')) == -1)
{
perror("ftok");
exit(-1);
}


//创建共享内存
if((shmid = shmget(key,N,IPC_CREAT|0666)) < 0 )
{
perror("shmget");
exit(-1);
}


if((semid = semget(key,2,IPC_CREAT|0666)) < 0)
{
perror("semget");
goto _error1;//信号灯创建失败,需将共享内存删除
}
init_sem(semid,s,2);


//映射共享内存到本进程地址空间
if((shmaddr = (char *)shmat(shmid,NULL,0)) == (char *)-1)
{
perror("shmat");
goto _error2;//映射失败,删除信号灯和共享内存
}


//创建子进程、
if((pid =fork()) < 0 )
{
perror("fork");
goto _error2;
}
//子进程代码--读取并处理共享内存的内容
else if(pid == 0)
{
char * p,* q;
while(1)
{
pv_sem(semid,READ,-1);
p = q = shmaddr;
while(*q)
{
if(*q != ' ')
{
*p = *q;
p++;
}
q++;
}
*p = '\0';
printf("%s",shmaddr);
pv_sem(semid,WRITE,1);
}
}
//父进程代码--向共享内存写内容
else
{
while(1)
{
pv_sem(semid,WRITE,-1);
printf("input >");
fgets(shmaddr, N, stdin);
if(strcmp(shmaddr,"quit\n") == 0)
break;
pv_sem(semid,READ,1);
}
kill(pid,SIGUSR1);

}


_error2:
semctl(semid,0,IPC_RMID);
_error1:
shmctl(shmid,IPC_RMID,NULL);
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37051576/article/details/79418050
今日推荐