管道:没有数据的类型,数据遵守“先进先出”的原则。
消息队列:加强型的管道,他可以指定存放的数据类型,与取走的数据类型,方便不同进程取数据。
消息队列,共享内存,信号量:属于system V(5) 版本的进程通信,也叫ipc通信对象,除了system V进程间的通信外,我们还有POSIX版本的。
查看system V (5)版本的通信对象命令:
查看消息队列: ipcs -q
查看共享内存: ipcs -m
查看信号量: ipcs -s
查看全部:ipcs -a
删除消息队列:
ipcrm -q (对象ID)
ipcrm -Q (键值)
消息队列的信息
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
(KEY值)(消息队列通信对象)
1.创建KEY值
#include
#include
key_t ftok(const char *pathname, int proj_id);
2.获取消息队列通信对象ID
#include
#include
#include
int msgget(key_t key, int msgflg);
参数一:键值key
参数二:权限
IPC_CREAT 创建
IPC_EXCL 检查是否存在
mode 0666
返回值:成功 返回 对象ID
失败 返回 -1
3.进行数据的交互
SYNOPSIS
#include
#include
#include
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数一:需要发送的消息队列ID
参数二:数据缓存区
参数三:数据的大小
参数四: 是否阻塞
0 阻塞
IPC_NOWAIT 不阻塞
返回值: 成功返回 0
失败返回 -1
PS,PS,PS 注意!!!!
数据的缓冲区必须要定义为如下结构体:
struct msgbuf {
long mtype;
char mtext[1];
};
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
参数五:是否阻塞
0 阻塞
IPC_NOWAIT 不阻塞
返回值: 成功返回 读到的数据大小
失败返回 -1
4.销毁消息队列
#include
#include
#include
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数一:对象ID
参数二:控制命令 IPC_RMID -》删除
参数三:设置 获取的时候使用
返回值:成功 0
失败 -1
---------------------------------信号量---------------------------------------------------------------
信号量的作用: 保护共享资源防止进程之间的竞争。
信号量的版本分为两种:1.SYSTEM V 2.POSIX (有名 无名)
posix :有名信号量用于不同进程之间的数据保护
posix : 无名信号量用于不同线程之间的数据保护
POSIX版本的有名信号量的使用: 记得添加 posix的库文件 -lpthread
1. 创建信号量对象
#include
#include
#include
sem_t *sem_open(const char *name, int oflag);
O_CREAT -》创建
O_EXCL -》检查是否存在
打开失败 SEM_FAILED
sem_t *sem_open(const char *name, int oflag,
mode_t mode, unsigned int value);
2.对信号量进行P V 操作
p操作申请资源 -1 -> sem_wait(3), 等待申请
v操作释放资源 +1 -> sem_post(3), 释放
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
参数一:需要操作的信号量指针
返回值:成功0
失败-1
获取信号量的值:
#include
int sem_getvalue(sem_t *sem, int *sval);
参数一:需要获取的信号量指针
参数二:获取后的值保存的地方
返回值:成功 0
失败 -1
关闭信号量
#include
int sem_close(sem_t *sem);
销毁信号量
int sem_unlink(const char *name);
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct msgbuf
{
long mtype;
char mtext[1024];
};
int main()
{
key_t key=ftok("/home/gec",66);
if(key < 0)
{
perror("");
exit(0);
}
int msgid=0;
label:
msgid=msgget(key,IPC_CREAT|IPC_EXCL|0666);
if(msgid < 0)
{
if(errno == EEXIST)
{
char del[1024]={0};
sprintf(del,"ipcrm -Q %d",key);
system(del);
goto label;
}
}
else
{
printf("创建消息队列成功\n");
}
struct msgbuf date;
date.mtype = 123;
while(1)
{
scanf("%s",date.mtext);
msgsnd(msgid,&date,strlen(date.mtext),0);
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct msgbuf
{
long mtype;
char mtext[1024];
};
int main(int argc,char *argv[])
{
key_t key=ftok("/home/gec",66);
if(key < 0)
{
perror("");
exit(0);
}
int msgid=msgget(key,IPC_CREAT|0666);
if(msgid < 0)
{
perror("creat fail\n");
}
else
{
printf("创建消息队列成功\n");
}
while(1)
{
struct msgbuf date;
bzero(&date,sizeof(date));
msgrcv(msgid,&date,sizeof(date),123,0);
printf("date = %s\n",date.mtext);
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}