- 浏览: 1340975 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
chinaxy1:
...
ON DUPLICATE KEY UPDATE重复插入时更新 -
b_l_east:
不一定哦,就算大小相当,in 和 exists的性能也会很大差 ...
mysql查询语句in和exists二者的区别和性能影响 -
llp1990311:
[size=x-small][/size]
如何正确防御xss攻击 -
home198979:
q315506754 写道还是佩服写c的 用其它语言一样可以实 ...
玩转深度优先搜索算法 -
q315506754:
还是佩服写c的
玩转深度优先搜索算法
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_EXCL:和IPC_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);
}
发表评论
-
【转载】如何用Linux的命令正确识别cpu的个数和核数
2013-08-20 11:40 1925如何在Linux下cpu的个数和核数呢?googel了一下 ... -
redis2.6.9源码学习---ziplist
2013-05-16 12:05 1802ziplist相比之前分析的z ... -
redis2.6.9源码学习---zipmap
2013-05-02 17:03 2258在看此文件源码之前,先看到此文件头部的英文注释,以下是本人 ... -
redis2.6.9源码学习---zipmap
2013-05-02 14:22 0<div class="iteye-blog- ... -
非阻塞connect编程
2013-04-08 17:08 1760非阻塞模式有3种用途 1.三次握手同时做其他的处理。co ... -
C库需要注意的函数
2013-03-08 16:50 2271本文转自:http://hub.opensolaris ... -
redis2.6.9源码学习---adlist
2013-02-07 16:27 1321源码adlist.c adlist.h,先来看看adlist ... -
redis2.6.9源码学习---dict
2013-02-07 11:59 1504redis的hashtable------dict.c ... -
redis2.6.9源码学习---Big_Endian&Little_Endian
2013-02-04 10:50 2776在阅读redis源码/src/endianconv.c时遇 ... -
linux c学习笔记----SCTP基础客户/服务编程(setsockopt,sctp_sendmsg等)
2013-01-15 17:53 19707在编程之前先了解一下sctp套接字选项 setsoc ... -
linux c学习笔记----UDP基础客户/服务编程(sendto,recvfrom)
2013-01-14 18:01 53779sendto(经socket传送数据) 相关函数 ... -
linux c学习笔记----select函数详解
2013-01-11 17:25 20364select系统调用是用来让我们的程序监视多个文件句柄(fil ... -
linux c学习笔记----TCP基础客户/服务编程(socket,bind等)
2013-01-10 17:29 28464socket(建立一个socket通信) 相关 ... -
linux c学习笔记----互斥锁属性
2013-01-05 18:37 11552互斥锁属性 使用互斥锁(互斥)可以使线程按顺序执行。通 ... -
linux c学习笔记----线程属性
2013-01-04 17:38 4619一.线程属性 线程具有属性,用pthre ... -
linux c学习笔记----线程同步
2012-12-28 17:49 30271.互斥量 互斥变量用pthead_mutex_t数据类 ... -
linux c学习笔记----线程创建与终止
2012-12-14 17:32 13727进程原语 线程原语 描述 fork p ... -
linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)
2012-12-11 18:08 36799shmgetint shmget(key_t key, siz ... -
linux信号列表
2012-11-30 16:40 2871我们运行如下命令, ... -
linux c学习笔记----信号(sigaction,sigaddset,sigprocmask)
2012-11-30 16:23 15278sigaction(查询 ...
相关推荐
在Linux中,有四个关键的系统调用用于操作消息队列:msgget、msgctl、msgsnd和msgrcv。让我们详细探讨这些函数及其用途。 1. **msgget**: - `msgget`函数用于创建或获取一个消息队列的标识符。它的原型为`key_t ...
### Linux下C语言编程——进程通信与消息管理 #### 前言:Linux下的进程通信(IPC) 在现代操作系统中,进程间的通信(IPC)是非常重要的功能之一,它允许不同进程之间交换数据或同步状态。在Linux环境中,C语言是...
Linux中的消息队列由内核管理,通过系统调用msgget、msgsnd、msgrcv等进行操作。msgget用于创建或打开一个消息队列并获取其标识符,msgsnd用于向消息队列发送消息,而msgrcv则用于从消息队列接收消息。消息队列中的...
本文将深入探讨如何使用消息队列在两个不同的Linux进程中进行通信,基于提供的文件`msg_rcv.c`和`msg_send.c`,我们可以理解为接收端和发送端的实现。 ### 1. 消息队列的概念 消息队列是一种内核级的数据结构,它...
### Linux消息队列专题编程笔记 #### 一、消息队列基本概念 消息队列是一种进程间通信方式,它提供了一种从一个进程向另一个进程发送数据块的方式。与管道不同的是,管道遵循先进先出的原则,而消息队列允许消息...
在Linux中,消息队列的创建、操作和管理主要通过系统调用实现,如`msgget`用于创建或获取消息队列,`msgsnd`用于发送消息,`msgrcv`用于接收消息,而`msgctl`则用于对消息队列进行控制,比如设置权限、删除队列等。...
在Linux中,这些操作通常通过系统调用来完成,比如`msgget`用于创建或打开消息队列,`msgsnd`用于发送消息,`msgrcv`用于接收消息,而`msgctl`则可以进行更高级的操作,如控制权限、设置消息队列的属性等。...
1. **创建消息队列**:使用`msgget`系统调用创建一个新的消息队列,或者获取已存在的队列。需要指定一个唯一的键(通常使用`ftok`生成)和一组权限。 2. **定义消息结构**:自定义一个消息结构,包含要传递的数据...
总结,Linux消息队列是实现进程间通信的有效手段,通过`msgget`、`msgsnd`、`msgrcv`和`msgctl`等系统调用,可以方便地在进程间传递消息。在提供的示例中,`msgsend.c`负责发送消息,而`msgrecv.c`负责接收并处理...
在Linux操作系统中,进程间通信(IPC,Inter-Process Communication)是...以上就是关于“Linux C 进程间通信 消息队列”的详细介绍,通过理解和实践,你将能够熟练地在C语言环境中运用消息队列进行进程间的有效通信。
本资料主要涵盖四种基本的UNIX消息队列操作函数,它们是`msgget`、`msgrcv`、`msgsnd`和`msgctl`。以下是对这些函数的详细解释: 1. **msgget**: `msgget(key, msgflg)`函数用于创建一个新的消息队列或者获取已...
进程可以向队列发送消息(msgsnd),也可以从队列中接收消息(msgrcv)。消息队列具有持久性,即使发送消息的进程已经终止,消息仍然保留在队列中,可供其他进程接收。 在msgLucy.c中,程序创建了一个消息队列,并...
`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语言实现的消息队列操作,从而在实际项目中灵活运用这一有效的进程间通信工具。
本文将详细介绍消息队列的四个主要函数:msgget、msgctl、msgsnd和msgrcv。 1. **msgget**函数: `msgget`用于获取已存在的消息队列标识符或者创建一个新的消息队列。它需要包含`<sys/types.h>`、`<sys/ipc.h>`和`...
### Linux消息队列实现进程间通信实例详解 #### 一、消息队列概念与特性 消息队列是一种用于实现进程间通信(IPC)的技术手段,它允许一个进程将消息发送到另一个进程中。与命名管道类似,消息队列也能够解决进程...
在这个例子中,我们首先使用`ftok`生成一个键值,然后用`msgget`创建一个消息队列。接着,我们发送一个消息到队列,并使用`msgrcv`从队列中接收消息。最后,我们通过`msgctl`删除消息队列,以释放资源。 总结,...
`msgget(key, flags)`函数创建一个新的消息队列或返回已存在的队列。`key`通常基于`ftok()`函数生成,`flags`包含权限和选项。 2. **发送消息**: `msgsnd(msqid, msgp, msgsz, msgflg)`函数向消息队列发送一条...