`

linux c学习笔记----消息队列(ftok,msgget,msgsnd,msgrcv,msgctl)

阅读更多

 


ftok()

#include <sys/types.h>

#include <sys/ipc.h>

函数原型:

 key_t  ftok( const  char * pathname , int   proj_id  );

参数:

  pathname 就时你指定的文件名(该文件必须是存在而且可以访问的)id是子序号,虽         然为int,但是只有8个比特被使用(0-255)

返回值: 成功时候返回key_t 类型的key值,失败返回-1


msgget

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

函数原型: int    msgget ( key_t  key , int  msgflg );

函数描述:建立消息队列

参数:

msgget()函数的第一个参数是消息队列对象的关键字(key),函数将它与已有的消息队
列对象的关键字进行比较来判断消息队列对象是否已经创建。而函数进行的具体操作是 第二个参数,msgflg 控制的。它可以取下面的几个值:
IPC_CREAT 如果消息队列对象不存在,则创建之,否则则进行打开操作;
IPC_EXCLIPC_CREAT 一起使用(用”|”连接),如果消息对象不存在则创建之,否     则产生一个错误并返回。

返回值:

成功时返回队列ID,失败返回-1,错误原因存于error

EEXIST (Queue exists, cannot create)
EIDRM (Queue is marked for deletion)
ENOENT (Queue does not exist)
ENOMEM (Not enough memory to create queue)
ENOSPC (Maximum queue limit exceeded)




msgsnd函数:将消息送入消息队列

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h

函数原型:int  msgsnd ( int msgid ,  struct msgbuf*msgp , int msgsz, int msgflg );

参数说明:

传给msgsnd()函数的第一个参数msqid 是消息队列对象的标识符(由msgget()函数得

到),第二个参数msgp 指向要发送的消息所在的内存,第三个参数msgsz 是要发送信息     的长度(字节数),可以用以下的公式计算:
msgsz = sizeof(struct mymsgbuf) - sizeof(long);
第四个参数是控制函数行为的标志,可以取以下的值:
0,忽略标志位;
IPC_NOWAIT,如果消息队列已满,消息将不被写入队列,控制权返回调用函数的线
程。如果不指定这个参数,线程将被阻塞直到消息被可以被写入。

smgbuf结构体定义如下:

struct smgbuf

{

                     long   mtype;

                    char   mtext [x] ;  //长度由msgsz决定

}


msgflg 可设置为 IPC_NOWAIT 。如果消息队列已满或其他情况无法送入消息,则立即  返回 EAGIN

返回: 0 on success

-1 on error: errno = EAGAIN (queue is full, and IPC_NOWAIT was asserted)
EACCES (permission denied, no write permission)
EFAULT (msgp address isn't accessable – invalid)
EIDRM (The message queue has been removed)
EINTR (Received a signal while waiting to write)
EINVAL (Invalid message queue identifier, nonpositive
message type, or invalid message size)
ENOMEM (Not enough memory to copy message buffer)


msgrcv函数:从消息队列中读取消息

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

函数定义:int  msgrcv( int  msgid , struct   msgbuf*  msgp ,  int msgsz ,  long msgtyp, int msgflg);

参数:

函数的前三个参数和msgsnd()函数中对应的参数的含义是相同的。第四个参数mtype

指定了函数从队列中所取的消息的类型。函数将从队列中搜索类型与之匹配的消息并将 返回。不过这里有一个例外。如果mtype 的值是零的话,函数将不做类型检查而自动返     回队列中的最旧的消息。第五个参数依然是是控制函数行为的标志,取值可以是:
0,表示忽略;
IPC_NOWAIT,如果消息队列为空,则返回一个ENOMSG,并将控制权交回调用函数
的进程。如果不指定这个参数,那么进程将被阻塞直到函数可以从队列中得到符合条件 消息为止。如果一个client 正在等待消息的时候队列被删除,EIDRM 就会被返回。如果     进程在阻塞等待过程中收到了系统的中断信号,EINTR 就会被返回。
MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,
剩下的部分被丢弃了。如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不     被取出。
当消息从队列内取出后,相应的消息就从队列中删除了。

msgbuf:结构体,定义如下:

struct msgbuf

{

                      long  mtype ;  //信息种类

                       char   mtest[x];//信息内容   ,长度由msgsz指定

}


msgtyp:  信息类型。 取值如下:

 msgtyp = 0 ,不分类型,直接返回消息队列中的第一项

 msgtyp > 0 ,返回第一项 msgtyp与 msgbuf结构体中的mtype相同的信息

msgtyp <0 , 返回第一项 mtype小于等于msgtyp绝对值的信息


msgflg:取值如下:

IPC_NOWAIT ,不阻塞

IPC_NOERROR ,若信息长度超过参数msgsz,则截断信息而不报错。



返回值:

成功时返回所获取信息的长度,失败返回-1,错误信息存于error

Number of bytes copied into message buffer
-1 on error: errno = E2BIG (Message length is greater than
msgsz,no MSG_NOERROR)
EACCES (No read permission)
EFAULT (Address pointed to by msgp is invalid)
EIDRM (Queue was removed during retrieval)
EINTR (Interrupted by arriving signal)
EINVAL (msgqid invalid, or msgsz less than 0)
ENOMSG (IPC_NOWAIT asserted, and no message exists in the queue to satisfy the request)

 

 

 

 例子:

server.c


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/msg.h>
#define MSG_FILE "server.c"
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSR
struct msgtype {
long mtype;
char buffer[BUFFER+1];
};
int main()
{
struct msgtype msg;
key_t key;
int msgid;
if((key=ftok(MSG_FILE,'a'))==-1)
{
fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno));
exit(1);
}
if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1)
{
fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));
exit(1);
}
while(1)
{
msgrcv(msgid,&msg,sizeof(struct msgtype),1,0);
fprintf(stderr,"Server Receive:%s\n",msg.buffer);
msg.mtype=2;
msgsnd(msgid,&msg,sizeof(struct msgtype),0);
}
exit(0);
}

 client.c


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#define MSG_FILE "server.c"
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSR
struct msgtype {
long mtype;
char buffer[BUFFER+1];
};
int main(int argc,char **argv)
{
struct msgtype msg;
key_t key;
int msgid;
if(argc!=2)
{
fprintf(stderr,"Usage:%s string\n\a",argv[0]);
exit(1);
}
if((key=ftok(MSG_FILE,'a'))==-1)
{
fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno));
exit(1);
}
if((msgid=msgget(key,PERM))==-1)
{
fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));
exit(1);
}
msg.mtype=1;
strncpy(msg.buffer,argv[1],BUFFER);
msgsnd(msgid,&msg,sizeof(struct msgtype),0);
memset(&msg,'\0',sizeof(struct msgtype));
msgrcv(msgid,&msg,sizeof(struct msgtype),2,0);
fprintf(stderr,"Client receive:%s\n",msg.buffer);
exit(0);
}

 

分享到:
评论

相关推荐

    消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例

    在Linux中,有四个关键的系统调用用于操作消息队列:msgget、msgctl、msgsnd和msgrcv。让我们详细探讨这些函数及其用途。 1. **msgget**: - `msgget`函数用于创建或获取一个消息队列的标识符。它的原型为`key_t ...

    Linux下C语言编程--进程通信、消息管理

    ### Linux下C语言编程——进程通信与消息管理 #### 前言:Linux下的进程通信(IPC) 在现代操作系统中,进程间的通信(IPC)是非常重要的功能之一,它允许不同进程之间交换数据或同步状态。在Linux环境中,C语言是...

    xxjyjy5.rar_LINUX消息队列_linux 消息队列_linux 消息_linux 消息队列_消息队列

    Linux中的消息队列由内核管理,通过系统调用msgget、msgsnd、msgrcv等进行操作。msgget用于创建或打开一个消息队列并获取其标识符,msgsnd用于向消息队列发送消息,而msgrcv则用于从消息队列接收消息。消息队列中的...

    linux两不同进程用消息队列通信

    本文将深入探讨如何使用消息队列在两个不同的Linux进程中进行通信,基于提供的文件`msg_rcv.c`和`msg_send.c`,我们可以理解为接收端和发送端的实现。 ### 1. 消息队列的概念 消息队列是一种内核级的数据结构,它...

    linux消息队列专题编程笔记.docx

    ### Linux消息队列专题编程笔记 #### 一、消息队列基本概念 消息队列是一种进程间通信方式,它提供了一种从一个进程向另一个进程发送数据块的方式。与管道不同的是,管道遵循先进先出的原则,而消息队列允许消息...

    消息队列源码-Linux.zip

    在Linux中,消息队列的创建、操作和管理主要通过系统调用实现,如`msgget`用于创建或获取消息队列,`msgsnd`用于发送消息,`msgrcv`用于接收消息,而`msgctl`则用于对消息队列进行控制,比如设置权限、删除队列等。...

    Linux下的消息队列测试程序,helloworld MessageTest

    在Linux中,这些操作通常通过系统调用来完成,比如`msgget`用于创建或打开消息队列,`msgsnd`用于发送消息,`msgrcv`用于接收消息,而`msgctl`则可以进行更高级的操作,如控制权限、设置消息队列的属性等。...

    linux使用消息队列实现进程间双向通信

    1. **创建消息队列**:使用`msgget`系统调用创建一个新的消息队列,或者获取已存在的队列。需要指定一个唯一的键(通常使用`ftok`生成)和一组权限。 2. **定义消息结构**:自定义一个消息结构,包含要传递的数据...

    linux 消息队列使用示例

    总结,Linux消息队列是实现进程间通信的有效手段,通过`msgget`、`msgsnd`、`msgrcv`和`msgctl`等系统调用,可以方便地在进程间传递消息。在提供的示例中,`msgsend.c`负责发送消息,而`msgrecv.c`负责接收并处理...

    linux c 进程间通信 消息队列

    在Linux操作系统中,进程间通信(IPC,Inter-Process Communication)是...以上就是关于“Linux C 进程间通信 消息队列”的详细介绍,通过理解和实践,你将能够熟练地在C语言环境中运用消息队列进行进程间的有效通信。

    四种UNIX消息队列操作函数.rar_C 消息队列_消息队列 _消息队列 unix

    本资料主要涵盖四种基本的UNIX消息队列操作函数,它们是`msgget`、`msgrcv`、`msgsnd`和`msgctl`。以下是对这些函数的详细解释: 1. **msgget**: `msgget(key, msgflg)`函数用于创建一个新的消息队列或者获取已...

    基于网络编程中的消息队列

    进程可以向队列发送消息(msgsnd),也可以从队列中接收消息(msgrcv)。消息队列具有持久性,即使发送消息的进程已经终止,消息仍然保留在队列中,可供其他进程接收。 在msgLucy.c中,程序创建了一个消息队列,并...

    msgget_msgget_

    `msgget()`、`msgsnd()` 和 `msgrcv()` 是与消息队列操作相关的三个关键函数,它们在C语言编程中被广泛使用。本文将详细介绍这三个函数以及如何进行基础实验。 ### 1. msgget() `msgget()` 函数用于创建一个新的...

    消息队列通信

    `msgctl` 函数用于控制消息队列的状态,例如删除消息队列。 ```c int msgctl(int msqid, int cmd, struct msqid_ds *buf); ``` - `msqid`: 消息队列的标识符。 - `cmd`: 执行的操作命令,如 IPC_RMID 表示删除消息...

    进程间通信:消息队列示例代码

    在Linux系统编程中,进程间通信(IPC, Inter-Process Communication)是多个进程协同...通过学习和理解消息队列的工作原理以及示例代码,开发者可以更好地掌握进程间通信的技巧,从而编写更高效、稳定的多进程应用。

    消息队列接口封装

    消息队列是操作系统提供的一种进程间通信(IPC)机制,它允许不同的进程之间...通过学习和理解这些代码,开发者可以更好地掌握Linux下C语言实现的消息队列操作,从而在实际项目中灵活运用这一有效的进程间通信工具。

    消息队列4个函数[归纳].pdf

    本文将详细介绍消息队列的四个主要函数:msgget、msgctl、msgsnd和msgrcv。 1. **msgget**函数: `msgget`用于获取已存在的消息队列标识符或者创建一个新的消息队列。它需要包含`&lt;sys/types.h&gt;`、`&lt;sys/ipc.h&gt;`和`...

    Linux消息队列实现进程间通信实例详解

    ### Linux消息队列实现进程间通信实例详解 #### 一、消息队列概念与特性 消息队列是一种用于实现进程间通信(IPC)的技术手段,它允许一个进程将消息发送到另一个进程中。与命名管道类似,消息队列也能够解决进程...

    linux 消息队列

    在这个例子中,我们首先使用`ftok`生成一个键值,然后用`msgget`创建一个消息队列。接着,我们发送一个消息到队列,并使用`msgrcv`从队列中接收消息。最后,我们通过`msgctl`删除消息队列,以释放资源。 总结,...

    linux c 进程间通信,使用共享内存和消息队列

    `msgget(key, flags)`函数创建一个新的消息队列或返回已存在的队列。`key`通常基于`ftok()`函数生成,`flags`包含权限和选项。 2. **发送消息**: `msgsnd(msqid, msgp, msgsz, msgflg)`函数向消息队列发送一条...

Global site tag (gtag.js) - Google Analytics