UNIX系统通讯--学习笔记
1.IPC
--IPC系统简介
-IPC进程间通讯(Interprocess Communication)
1.消息队列(Message queue,q):应用与不同进程间少量数据的顺序共享
2.信号量(Semaphore,s):应用与进程之间的同步与互斥的控制
3.共享内存(Share Memory,m):应用与进程之间大批量数据的随即共享访问
1.1 查询IPC对象
shell命令ipcs查询当前系统的ipc对象信息
命令:ipcs[options]
-q 只查询ipc对象中的消息队列
-s 只查询ipc对象中的信号量
-m 只查询ipc对象中的共享内存
-a 查询ipc对象的全部属性
默认 -qsm
IPC对象的标识号ID:
-标识号为非负整数,unix通过标识号在系统唯一确定IPC对象。
-不同类型IPC对象的标识号可以相同,但同类型IPC对象的标识号一定唯一。
IPC对象的关键字KEY
-创建IPC对象,必须指定一个IPC关键字,为一个32位的整数。
1.2 删除IPC对象
shell命令ipcrm可以删除IPC对象信息
命令:ipcrm[options]
-q id 删除标识号为id的消息队列
-Q key 删除关键字为key的消息队列
-s id 删除标识号为id的信号量
-S key 删除关键字为key的信号量
-m id 删除标识号为id的共享内存
-M key 删除关键字为key的共享内存
ipcs -aq | grep 1234
chmod 777 msg_msgsnd1
./msg_msgsnd1
ipcsrm -q 1966292
ipcsrm -q 1234
1.3 IPC结构
/usr/include/sys/ipc.h
/* Common IPC Structures */
struct ipc_perm
{
uid_t uid;
gid_t gid;
uid_t cuid;
gid_t cgid;
mode_t mode;
unsigned short seq;
key_t key;
}
1.4 IPC内核限制
-消息队列:消息的最大长度,队列最大字节数,消息总数。
-信号量:最多可用信号量集,每个信号量集中最多的信号量个数,可用的信号量最大数。
--消息队列简介
-先进先出的队列数据结构,是一个链表。
2.1 消息队列结构
/usr/include/sys/msg.h
struct msqid_ds
{
struct ipc_perm msg_perm;
struct msg *msg_first;
struct msg *msg_last;
unsigned int msg_cbytes;
msgqnum_t msg_qnum;
msglen_t msg_qbytes;
pid_t msg_lspid;
pid_t msg_lrpid;
time_t msg_stime;
time_t msg_rtime;
time_t msg_ctime;
};
ipcs -aq
2.2 消息结构
/usr/include/sys/msg.h
struct msg
{
struct msg;
long msg;
short msg_ts;
short msg_sport;
};
struct msgbuf
{
long mtype;
char mtext[1]
};
--消息队列函数介绍
3.1 消息队列的创建
int msgget(key_t key,int msgflg);
-参数key是消息队列一关键字,具有唯一性。
-参数msgflg的低9位指定了队列的属主,属组和其他用户的访问权限,参数msgflg的其他位指定了
消息队列的创建方式。
* IPC_CREATE:创建消息队列,若存在就打开。
* IPC_EXCL:同IPC_CREATE一起使用,创建一个不存在的消息队列,若存在则函数调用失败。
vi msg_msgget.c
#include
#include
#include
#include
#include
extern int errno;
struct mymsgbuf
{
long mtype;
char ctext[100];
}
void main()
{
int msid;
struct mymsgbuf buf;
if((msid = msgget(0x1234,0666|IPC_CREAT)) < 0)
{
fprintf(stderr,"open msg %X failed.\n",0x1234);
return;
}
}
ipcs -q | grep 1234
cc -o msg_msgget msg_msgget.c
l msg_msgget
./msg_msgget
ipcs -aq | grep 1234
3.2 消息队列的发送
int msgsnd(int msqid,struct msgbuf *msgp,int msgsz,int msgflg);
* 参数msqid指定了发送消息队列的标识号。
* 参数msgp指向存储发送消息内容的内存地址。
* 参数msgsz指定发送消息数据的长度,不包括消息类型部分。
* 参数msgflg控制消息发送的方式。
* IPC_NOWAIT:消息采用非阻塞方式发送。
造成msgsnd()等待的条件有两种:
1.消息队列满:当前消息的大小与当前消息队列中的字节数之和超过了消息队列的总容量。
msg_cbytes + msgsz > msg_qbytes
2.消息总数满:系统中所有的消息队列的消息总数已经达到了操作系统的上限值。
vi msg_msgsnd.c
#include
#include
#include
#include
#include
extern int errno;
struct mymsgbuf
{
long mtype;
char ctext[100];
}
void main()
{
int msid;
struct mymsgbuf buf;
if((msid = msgget(0x1234,0666|IPC_CREAT)) < 0)
{
fprintf(stderr,"open msg %X failed.\n",0x1234);
return;
}
while(strncmp(buf.ctext,"exit",4))
{
memset(&buf,0,sizeof(buf));
fprintf(stderr,"Please input:");
fgets(buf.ctext,sizeof(buf.ctext),stdin);
buf.mtype = 1000;
while((msgsnd(msid,&buf,strlen(buf.ctext),0)) < 0)
{
if(errno == EINTR) continue;
return;
}
}
}
cc -o msg_msgsnd msg_msgsnd.c
ipcs -aq | grep 1234
ipcrm -Q 1234
./msg_msgsnd
ipcs -aq | grep 1234
3.3 消息队列的接收
3.4 消息队列的控制
--消息队列的常见应用模型
4.1 单消息队列完成(对等进程间)的双向通讯
4.2 双消息队列完成(对等进程间)的双向通讯
4.3 多消息队列完成(对等进程间)的双向通讯
4.4 单消息队列完成(客户-服务器进程间)的双向通讯
4.5 双消息队列完成(客户-服务器进程间)的双向通讯
4.6 多消息队列完成(客户-服务器进程间)的双向通讯
2.Socket
3.Tuxedo