1、ftok(3)
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
功能:创建一个消息队列的key值,
参数:
pathname:路径名称(可写任意一个文件路径)
proj_id :可使用好数字(1~255)
返回值:
成功:返回一个根据参数产生的key值。
失败:-1
2、msgget(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
功能:创建(或使用)一个消息队列。
参数:
key:由ftok()函数生成;
msgflg:一般设置为:CREAT|0644(即:创建一个本人可读写,其它人可读的消息队列。
返回值:
成功:返回一个正整数做为消息队列号;
失败:-1。
3、msgsnd(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
struct msgbuf {
long mtype; /* 消息类型,正整数即可 */
char mtext[256]; /* 需要发送数据的大小,可以填其它数值 */
} msgp;
功能:向消息队列里发送一个数据
参数:
msqid:msgget()函数的返回值;
msgp:填上面结构变量名称;
msgsz:消息的大小:sizeof(msgp)-sizeof(long)
msgflg:一般填IPC_NOWAIT。
返回值:
成功:0
失败:-1
4、msgrcv(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
功能:从消息队列里读取一条数据。
参数:
msgtyp:一般填写0。
msgsz:数值应大于或等于发送者的大小,才能取出一条数据 ,一般和发送者一样大。
其它:参见msgsnd()函数的参数。
返回值:
成功:返回得到的字节数;
失败:-1
通过消息队列完成进程间异步通信(发送者)代码举例:
/* ipc_send.c
功能:发消息队列里一次发送10条251字节的数据
*/
#include <strings.h>
#include <string.h>
#include "rand_h.h"
#include "unistd.h"
#define PATHNAME_PIDA "pathname." //定义路径宏
#define PROJ_ID 10 //定义编号宏
int main(void){
key_t key_id;
key_id = ftok(PATHNAME_PIDA,PROJ_ID);//创建一个消息队列key
int msg_id;
msg_id = msgget(key_id,IPC_CREAT|0664);//创建一个消息队列号
struct msgbuf{ //定义一个消息队列内容结构体
long mtype;
char mtext[256];
}msg_buf;
bzero(&msg_buf.mtext,256);//清空数组里的内容
msg_buf.mtype = 3;//设置消息队列类型
int str_num =0;
for(str_num = 0;str_num <10;str_num ++){
strcpy(msg_buf.mtext,rand_str(250));//通过随机函数,产生一个250字节字符串复制结构体的数组里
if(strlen(msg_buf.mtext)<256){//为数组加'\0'字符做了字符串结束标志
msg_buf.mtext[strlen(msg_buf.mtext)] ='\0';
}
else{
msg_buf.mtext[256] ='\0';
}
//向消息队列里发送数据。
msgsnd(msg_id,(void *)&msg_buf,\
sizeof(msg_buf)-sizeof(long),IPC_NOWAIT);
printf("%s\n",msg_buf.mtext);//显示发消息队列里发送数据的内容
sleep(1);
}
return 0;
}
/* rand_h.h
功能:随机数生成头文件
*/
#ifndef __RAND_H_H_ //头文件卫士框架
#define __RAND_H_H_
char rand_func(void);
char *rand_str(int);
#endif
/* rand_h.c
生成随机字符串
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <strings.h>
#include "rand_h.h"
char rand_func(void){
int func_num = rand() % 4;//产生0~3合计4种类型字符(大小写字母、数字、特殊字符
int num = 0; //保存生成的数字,用于转换为字符
char ch='\0';//保存产生的随机字符
int num_buf[5]={33,35,46,64,95};//特殊字符的ASCII码
switch(func_num){
case 0:
num = rand() % 10+48;//生成0~9数字对应的ASCII码
break;
case 1:
num = rand() %26 +97;//生成小写字母ASCII码
break;
case 2:
num = rand() %26 + 65;//生成大小写线ASCII码
break;
case 3:
num = num_buf[rand()%5];//生成特殊子符在数组里的下标并得到ASCII码
break;
default :
break;
}
sprintf(&ch,"%c",num);//将数字转换成ASCII对应的字符
return ch;//返回单次生成的字符
}
char *rand_str(int size){
srand(time(NULL));//产生随机数种子
char *str_p = malloc(size);//保存随机数的字符串地址。
bzero(str_p,size);//清空字符串里的内容
int buf_num = size;
while(size != 0){//调用size次,产生的字符保存到字符串里
str_p[buf_num-size] = rand_func();
size--;
}
return str_p;//返回保存字符器的地址给调用者.
}
发送者编译执行如下(通过IPCS命令可以查看消息队列):
ipc$gcc rand_h.c ipc_send.c -o send
ipc$./send
6O_8@5S10Nu9vJ!KOL1_C6QuF2o@tuv3_3ZU!3J1cq8dqsGxvjj!TY4tW0L_!RE!kW!_7X!FE#!7V9!2@#43.GM##65k2#k.@107.l_gP0Yk2x5R_._!H.m#xSvR4_j837Csac0P9z8#4h#f6UP#@bsraTHE.#7E.X14N#i4.187pV5jZ2mPMFOF6!35KB_ZV3!J4nL5t@RTS7_@dlrC3qLlh726U9@_Eh.h@A3x617.x4Xm_1HS841q!w
1X_nlKeRUpS3bVE823.z5brPbe7#TKz!fn0WxtTD#!08!.OVp1ufaHi.8!o@@t81@X_1e0L_M_G_5Upo7jR5#k80.fn#Pd8.f5CWg0292d_@s0#C41_uXBdRl!!vV!9D499#QPsu2LF01KqpN2Rmp292a!k#!CjxbXl0@nb!6hO#HJ8!tm1jwU!19oy5f@!@!_y.V1_vcyUJx2.4@m@VI@I1BO@!j4!S3!7c0_5C0Q31loNYPO#55jR!!_
.............
通过消息队列完成进程间异步通信(接收者)代码举例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <strings.h>
#include <string.h>
#define PATHNAME_PIDA "pathname."
#define PROJ_ID 10
int main(void){
key_t key_id;
key_id = ftok(PATHNAME_PIDA,PROJ_ID);
int msg_id;
msg_id = msgget(key_id,IPC_EXCL);
struct msgbuf{
long mtype;
char mtext[256];
}msg_buf;
bzero(&msg_buf.mtext,256);
msg_buf.mtype = 3;
msgrcv(msg_id,&msg_buf,sizeof(msg_buf)-sizeof(long),0,IPC_NOWAIT);
printf("%s\n",msg_buf.mtext);
return 0;
}
接收者编译执行如下(通过IPCS命令可以查看消息队列):
ipc$gcc ipc_recv.c -o recv
ipc$./recv
CG@5X!_.3RC_q.3Y_v32J8M.z_z#sn@.!LCUgJZxH@2!4A@@Zm.0Z_01d!aTGdW.k024.Q6@w@30V@A1C48416thspN..7446in56w.g@n2rF2wlws!!YCFBiB952daG66N4.Dd@v1o9o#79cn!8@@.K0H#I5R@QF30@K#jH4X_.N7_jnLn2#Wqlv23!4@O8Yd@@j_S!5_CSRpll_@6y666i.4O7!P.3tqM0K11@yHU02_t!!f_!t82D28
ipc$./recv
3!P2P!T0#.QF!QHr7!HyQsj!S22E84am.z!MJSx7.0#7CyHJ#@lh1@ci37_Xgb!aYvm@E!O_oC5dzqUDS9F4L@!.#5#iu946Pr9gj!6v5J!_p1Q#kcL97.K!TRhEk1F!3G4mK0tZ05A10P##Nm@Z.ck.5@Dk@jcLoFYN!c6A8@o363K2Kh.O@N18_K#hf95.#_83B_3!X@1rHsSmk7P65#S._A@w01@cLuVsoBF54bzno4!1!X!0@!5Cu!
05ipc$vim ipc_recv.c