信号量与共享内存实现不同进程间通讯
通过信号量与共享内存实现不同进程间通讯
头文件:myshm.h
#ifndef __MYSHM_H__
#define __MYSHM_H__
#define KEYPATH "/etc"
#define SEMPRJ 'a'
#define SHMPRJ 'b'
#define NAMESIZE 1024
struct stu_st //自定义传输数据类型
{
char name[NAMESIZE];
int math;
int chinese;
};
#endif
发送方:sender.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "myshm.h"
static void P(int semid,int num) //P操作信号量减一
{
struct sembuf set;
set.sem_num = num; //信号量数组中的哪一个
set.sem_op = -1; //减一操作
set.sem_flg = 0; //无特殊要求
semop(semid,&set,1); //设置信号量(信号量ID,设置信息,设置多少个信号量)
}
static void V(int semid,int num) //V操作信号量加一
{
struct sembuf set;
set.sem_num = num; //信号量数组中的哪一个
set.sem_op = 1; //加一操作
set.sem_flg = 0; //无特殊要求
semop(semid,&set,1); //设置信号量(信号量ID,设置信息,设置多少个信号量)
}
int main()
{
key_t semkey,shmkey;
int semid,shmid;
struct stu_st *std;
int ret;
semkey = ftok(KEYPATH,SEMPRJ); //申请信号量key值
if(semkey <0)
{
perror("ftok semkey()");
exit(1);
}
shmkey = ftok(KEYPATH,SHMPRJ); //申请共享内存key值
if(shmkey <0)
{
perror("ftok shmkey()");
exit(1);
}
semid = semget(semkey,2,IPC_CREAT|0600); //创建信号量 (key,多少个信号量,属性)
if(semid <0)
{
perror("semget()");
exit(1);
}
shmid = shmget(shmkey,sizeof(*std),IPC_CREAT|0600); //创建共享内存 (key,共享内存大小,属性)
if(shmid <0)
{
perror("shmget()");
exit(1);
}
ret = semctl(semid,0,SETVAL,1); //设置信号量(信号量ID,哪个信号量,操作命令,参数)
if(ret<0)
{
perror("semctl");
exit(1);
}
ret = semctl(semid,1,SETVAL,0); //设置信号量(信号量ID,哪个信号量,操作命令,参数)
if(ret<0)
{
perror("semctl");
exit(1);
}
std = shmat(shmid,NULL,0); //映射共享内存
if(std == (void *)-1)
{
perror("shmat");
exit(1);
}
P(semid,0); //P操作
strcpy(std->name,"Alin"); //共享内存设置数据
std->math = 100;
std->chinese = 30;
V(semid,1); //V操作
P(semid,0); //P操作
shmdt(std); //取消共享内存映射
shmctl(shmid,IPC_RMID,NULL); //删除共享内存ID
semctl(semid,0,IPC_RMID), //删除信号量ID
semctl(semid,1,IPC_RMID);
exit(0);
}
接收方:rcver.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "myshm.h"
static void P(int semid,int num)
{
struct sembuf set;
set.sem_num = num;
set.sem_op = -1;
set.sem_flg = 0;
semop(semid,&set,1);
}
static void V(int semid,int num)
{
struct sembuf set;
set.sem_num = num;
set.sem_op = 1;
set.sem_flg = 0;
semop(semid,&set,1);
}
int main()
{
key_t semkey,shmkey;
int semid,shmid;
struct stu_st *std;
int ret;
semkey = ftok(KEYPATH,SEMPRJ);
if(semkey <0)
{
perror("ftok semkey()");
exit(1);
}
shmkey = ftok(KEYPATH,SHMPRJ);
if(shmkey <0)
{
perror("ftok shmkey()");
exit(1);
}
semid = semget(semkey,2,0); //运行sender时已创建这里不需要重复创建
if(semid <0)
{
perror("semget()");
exit(1);
}
shmid = shmget(shmkey,sizeof(*std),0); //运行sender时已创建这里不需要重复创建
if(shmid <0)
{
perror("shmget()");
exit(1);
}
ret = semctl(semid,0,SETVAL,1);
if(ret<0)
{
perror("semctl");
exit(1);
}
ret = semctl(semid,1,SETVAL,0);
if(ret<0)
{
perror("semctl");
exit(1);
}
std = shmat(shmid,NULL,0);
if(std == (void *)-1)
{
perror("shmat");
exit(1);
}
P(semid,1);
printf("name:%s math:%d chinese:%d\n",std->name,std->math,std->chinese); //输出共享内存内容
V(semid,0);
shmdt(std);
shmctl(shmid,IPC_RMID,NULL);
semctl(semid,0,IPC_RMID);
exit(0);
}
编译文件:Makefile
all:rcver sender
rcver:rcver.o
$(CC) $^ -o $@
sender:sender.o
$(CC) $^ -o $@
clean:
$(RM) *.o rcver sender
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!