- 浏览: 77160 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
qswdit:
哥们 话说文中CAS 提供扩展认证 是怎么进行的啊!! 求详 ...
单点登陆(SSO)CAS介绍 -
liuxuejin:
这样的资料是在是太少了
lame+ffmpeg+flvtool2+mencoder -
kfc_davy:
NICE ~ 有点少了http://hi.baidu.com ...
ubuntu下安装Tokyo Tyrant(ttserver) -
kkppccdd:
请问付费怎么付的?大陆的信用卡申请不了google check ...
搜搜工作网正式迁移到Google App Engine -
gqf2008:
CLASSPATH=$CLASSPATH:/usr/local ...
Tokyo Tyrant(ttserver) java api的安装
基本概念 1.队列 队列是信息的线性表,它的访问次序是先进先出(FIFO)。也就是说,置入队列中的 第一个数据项将是从队列中第一次读出的数据项,置入的第二项将是读出的第二项,依 此类推。这是队列允许的唯一存取操作,其它随机访问是不允许的。这种数据结构保证 对数据资源的请求将严格按照先后顺序进行,因而可用于对事件的调度并起到I/O缓冲 的作用。 2.报文 发送进程和接收进程进行信息的交换,一般是通过将信息划分为若干段放入数据交 换缓冲器中,进程间通过对该缓冲器的存取来实现通信。因此,数据是以不连续的形式 在进程间传送,这些不连续的部分就叫报文。 3.消息队列 将报文按队列的结构进行组织就叫消息队列。该队列用于存放正被发送或接收的 每一个报文的标题信息。每一个消息队列还对应有一个数据结构,它含有消息队列的 存取权限,和消息队列的当前状态信息等信息。消息队列可进行"发送"和"接收"操作。 消息队列的编程要点及运作过程 1.消息队列的创建 在报文能够发送和接收之前,必须创建一个能够唯一被识别出的消息队列和数据结 构,这个被创建的唯一标识符叫做消息队列描述符(msqid),用来识别或引用相关的消 息队列和数据结构。用msgget(longkey,intmsgflg)系统调用来创建消息队列,其中 key是一个长整型,可由用户设定也可通过ftok()获得。msgflg的值是八进制的消息队 列操作权和控制命令的组合。操作权定义为: 操作允许权八进制整数 用户可读0400 用户可写0200 同组可读0040 同组可写0020 其它可读0004 其它可写0002 可取IPC_CREAT或IPC_EXCL。如果要创建一个key=888且属主和同组可读写的消息队列, 执行以下系统调用msgget(0x888,0660|IPC_CREAT)。创建后可用ipcs命令看到以下信 息: Jan2506:49:521970 TIDKEYMODEOWNERGROUP MessageQueues: .q70x00000888--rw-rw rootsystem ... 。如果执行msgget(0x888,0660|IPC_CREAT)时,与0x888对应的消息队列已存在,则返 回该消息队列的描述符msqid。 消息队列一经创建即可用msgsnd(intmsqid,void*msgp,size_tmsgsz,intmsgflg) 发送消息。msgqid是经msgget创建的消息队列描述符,msgp是指向消息段的指针,该 指针所指结构含有报文类型和要发送或接收的报文: structmsgbuf{ longmtype;/*消息类型*/ charmtext[512]; /*消息正文,512暂定为消息段的大小*/ } 确定。msgflg是当消息队列满时(队列中无空闲空间),系统要采取的行动.如果 msgflg&IPC_NOWAIT=真,调用进程立即返回,不发送该消息。如果 msgflg&IPC_NOWAIT=假,调用进程暂停执行,处于"挂起"状态,且不发送该消息。直到 下列情况之一出现: signal中描述的方式执行。 如果msgsnd返回0则发送成功。返回-1则表示发送失败,错误类型可具体查看 errno。 3.消息的接收 用msgrcv(intmsqid,void*msgp,size_tmsgsz,longmsgtyp,intmsgflg)系统调用从 msqid消息队列中读取一条信息并将其放入消息段指针msgp指向的结构。msgsz给出 mtext的字节数,如果所接收的消息比msgsz大且msgflg&MSG_NOERROR为真,则按msgsz 的大小截断而不通知调用进程。msgtyp指定要求的消息类型: msgtyp=0接收消息队列中的第一个报文 当队列上没有所期望类型的消息或消息队列为空时msgflg指出调用进程要采取的 行动:如果msgflg&IPC_NOWAIT为真,则调用进程立即结束并返回-1。如 msgflg&IPC_NOWAIT为假,则调用进程暂停执行直至出现: 队列中放入所需类型的消息,调用进程接收该消息 。 如果msgrev执行成功,则返回放入mtext中的字节数,失败返回-1,错误类型可查 errno。 4.消息队列的控制和撤销 用msgctl(intmsqid,intcmd,structmsqid_ds*buf)系统调用实现对消息队列的控 制。msgqid必须是用msgget创建的消息队列描述符。cmd可以是: IPC_STAT查看消息队列的状态,结果放入buf指针指向的结构 四、编程示例 下面给出一个运用消息队列,实现进程通信的实例。以下程序在IBMRS/6000小型机 (AIX操作系统)上和IBMPC(UNIX操作系统)上分别调试通过。该程序主要模拟根据 帐号查询余额的过程。包括三方面: 请求进程从标准输入读入帐号,并将该帐号通过消息队列发送给服务进程; 服务进程接收该帐号后,按照请求的先后顺序在标准输入上输入该帐户的姓名和余额, 并将结果返回给客户进程; 请求进程接收返回的信息,并将结果输出在标准输出上。 号,可同时起动多个请求进程。 程序在HP-unix有点问题!! C,S都生成ID一样的消息队列 #include <unistd.h> extern int errno; int main(int argc, char **argv)
sprintf(sndbuf.mtext,"%2.2s",argv[1]); sndbuf.mtext[6]=0; rtrn=msgrcv(msqid,msgp, 100, atoi(argv[1]), 0); sscanf(rcvbuf.mtext,"%[^|]|%lf",name,&balance); /*服务方程序msgcenter.c*/ static struct msgbuf1 extern int errno; int main() while(1)
eg.2 编写了012号与013号程序,分别是关于消息队列和共享内存的,在机器上也已经调试过了,现在把代码贴在下面:
操作权可相加而派生,如用户可"读"、"写"的权限为0400|0200=0600。控制命令
IPCstatusfrom/dev/memasofSun
它的消息队列描述符是7,属主是root,同组是system,存取权是属主、用户可读写
2.消息的发送
msgsz是msgp参量指向的数据结构中字符数组的长度,即报文长度,最大值由MSGMAX
引起暂停的条件不再存在,如队列出现空闲,即可发送
该消系队列被从系统中删去
调用进程接收到一个要捕捉的信号,如中断信号,此时不发送消息,调用进程按
msgtyp>0接收消息队列中的类型为msgtyp的第一个报文
msgtyp<0接收消息队列中小于等于msgtyp绝对值的最低类型的第一个报文
msqid消息队列从系统中删除
调用进程接收到捕获的信号,此时不接收消息,调用进程按signal描述的方式执行
IPC_SET为消息队列设置属主标识,同组标识,操作允许权,最大字节数
IPC_RMID删除指定的msqid以及相关的消息队列和结构
服务进程(msgcenter)先于请求进程(msgreq)启动.客户进程启动时要携带请求编
而且要加两个头文件:#include <stdlib.h> #include <string.h>
/*请求方程序msgreq.c*/
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static struct msgbuf1
{
long mtype;
char mtext[100];
} sndbuf, rcvbuf, *msgp ;
{
int rtrn, msqid ;
char name[10];
double balance;
if (argc!=2)
{
fprintf(stderr,"msgreq [01-99]\n"); exit(-1);
}
if ((msqid = msgget(0x888, IPC_CREAT|0660)) == -1 )
{
fprintf(stderr, "msgget 888 failed !\n");
//exit(-1);
}
msgp=&sndbuf;
printf("输入4位帐号:");
scanf("%s",&sndbuf.mtext[2]);
msgp->mtype=666;
rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0);
if (rtrn==-1)
{
perror("msgsnd"); exit(-1);
}
msgp=&rcvbuf;
fprintf(stderr,"等待后台数据处理进程的回答....");
if(rtrn==-1)
{
perror("msgrcv"); exit(-1);
}
printf("\n姓名=%s\n",name);
printf("余额=%lf\n",balance);
}
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
{
long mtype;
char mtext[100];
} sndbuf, rcvbuf , *msgp;
{
int rtrn, msqid ;
char strbuf[100];
if ( (msqid = msgget(0x888, IPC_CREAT|0600)) == -1 )
{
fprintf(stderr, "msgget 888 failed !\n"); exit(-1);
}
{
msgp=&rcvbuf;
fprintf(stderr,"等待前台进程的请求....");
rtrn=msgrcv(msqid, msgp, 100, 666 ,MSG_NOERROR);
if(rtrn==-1)
{
perror("msgrcv");exit(-1);
}
msgp=&sndbuf;
sprintf(strbuf,"%2.2s\0",rcvbuf.mtext);
msgp->mtype=atoi(strbuf);
printf("\n输入帐号=%4.4s的帐户姓名:",&rcvbuf.mtext[2]);
scanf("%s",sndbuf.mtext);
strcat(sndbuf.mtext,"|");
printf("输入该帐户余额:");
scanf("%s",strbuf);
strcat(sndbuf.mtext,strbuf);
rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0);
if (rtrn==-1)
{
perror("msgsnd");
exit(-1);
}
}
}
/*********************程序相关信息*********************
程序编号:012
程序编写起始日期:2008.11.1
程序编写完成日期:2008.11.1
程序修改日期: 修改备注:
程序目的:学习linux消息队列通信
所用主要函数:msgget(),msgsnd(),msgrcv(),msgctl()
程序存疑:
程序完成地点: 宿舍内
*********************程序相关信息*********************/
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int pid,msqid;//后者为消息队列识别代号
struct msgbuf
{
long mtype;//消息类型
char mtext[20];//消息内容
}send_buf,receive_buf;
if((msqid=msgget(IPC_PRIVATE,0700))<0)//建立消息队列
{
printf("msgget建立消息队列失败。\n");
exit(1);
}
else
printf("msgget建立消息队列成功,该消息队列识别代号为%d。\n",msqid);
if((pid=fork())<0)
{
printf("fork()函数调用失败!\n");
exit(2);
}
else if(pid>0)//父进程,发送消息到消息队列
{
send_buf.mtype=1;
strcpy(send_buf.mtext,"My test information");
printf("发送到消息队列的信息内容为:%s\n",send_buf.mtext);
if(msgsnd(msqid,&send_buf,20,IPC_NOWAIT)<0)//发送send_buf中的信息到msqid对应的消息队列
{
printf("msgsnd消息发送失败。\n");
exit(3);
}
else
printf("msgsnd消息发送成功。\n");
sleep(2);
exit(0);
}
else//子进程,从消息队列中接收消息]
{
sleep(2);//等待父进程发送消息完成
int infolen;//读到的信息数据长度
if((infolen=msgrcv(msqid,&receive_buf,20,0,IPC_NOWAIT))<0)//自消息队列接收信息
{
printf("msgrcv读取信息错误。\n");
exit(4);
}
else
printf("msgrcv读取信息成功。\n");
printf("自消息队列读取到的内容为%s,共读取%d个字节。\n",receive_buf.mtext,infolen);
if((msgctl(msqid,IPC_RMID,NULL))<0)//删除msqid对应的消息队列
{
printf("msgctl函数调用出现错误。\n");
exit(5);
}
else
{
printf("识别代号为%d的消息队列已经被成功删除。\n",msqid);
exit(0);
}
}
}
/*********************程序运行结果*********************
[root@localhost temp]# ./msg
msgget建立消息队列成功,该消息队列识别代号为98304。
发送到消息队列的信息内容为:My test information
msgsnd消息发送成功。
msgrcv读取信息成功。
自消息队列读取到的内容为My test information,共读取20个字节。
识别代号为98304的消息队列已经被成功删除。
***********************************************************/
/*********************程序相关信息*********************
程序编号:013
程序编写起始日期:2008.11.1
程序编写完成日期:2008.11.1
程序修改日期: 修改备注:
程序目的:学习linux共享内存
所用主要函数:shmget(),shmat(),shmctl(),shmdt()
程序存疑:
程序完成地点: 宿舍内
*********************程序相关信息*********************/
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
int main()
{
int pid,shmid;//后者为共享内存识别代号
char *write_address;
char *read_address;
struct shmid_ds dsbuf;
if((shmid=shmget(IPC_PRIVATE,32,0))<0)//分配共享内存
{
printf("shmid共享内存分配出现错误。\n");
exit(1);
}
else
printf("shmid共享内存分配成功,共享内存识别代号为:%d。\n",shmid);
if((pid=fork())<0)
{
printf("fork函数调用出现错误!\n");
exit(2);
}
else if(pid>0)//父进程,向共享内存中写入数据
{
printf("父进程的ID是:%d\n",getpid());
write_address=(char *)shmat(shmid,NULL,0);//连接共享内存
if((int)write_address==-1)
{
printf("shmat连接共享内存错误。\n");
exit(3);
}
else
{
printf("shmat连接共享内存成功。\n");
strcpy(write_address,"我是写入共享内存的测试数据");//将数据写入共享内存
printf("写入共享内存的信息为“%s”。\n",write_address);
if((shmdt((void *)write_address))<0)//断开与共享内存的连接
printf("shmdt共享内存断开错误。\n");
else
printf("shmdt共享内存断开成功。\n");
sleep(2);
return;
}
}
else//子进程,从共享内存中读取数据
{
sleep(2);//等待父进程写入共享内存完毕
printf("子进程ID是:%d\n",getpid());
if((shmctl(shmid,IPC_STAT,&dsbuf))<0)
{
printf("shmctl获取共享内存数据结构出现错误。\n");
exit(4);
}
else
{
printf("shmctl获取共享内存数据结构成功。\n建立这个共享内存的进程ID是:%d\n",dsbuf.shm_cpid);
printf("该共享内存的大小为:%d\n",dsbuf.shm_segsz);
if((read_address=(char *)shmat(shmid,0,0))<0)//连接共享内存
{
printf("shmat连接共享内存出现错误。\n");
exit(5);
}
else
{
printf("自共享内存中读取的信息为:“%s”。\n",read_address);
printf("最后一个操作该共享内存的进程ID是:%d\n",dsbuf.shm_lpid);
if((shmdt((void *)read_address))<0)//断开与共享内存的连接
{
printf("shmdt共享内存断开错误。\n");
exit(6);
}
else
printf("shmdt共享内存断开成功。\n");
if(shmctl(shmid,IPC_RMID,NULL)<0)//删除共享内存及其数据结构
{
printf("shmctl删除共享内存及其数据结构出现错误。\n");
exit(7);
}
else
printf("shmctl删除共享内存及其数据结构成功。\n");
exit(0);
}
}
}
}
/*********************程序运行结果*********************
[root@localhost temp]# ./shm
shmid共享内存分配成功,共享内存识别代号为:1703947。
父进程的ID是:7647
shmat连接共享内存成功。
写入共享内存的信息为“我是写入共享内存的测试数据”。
shmdt共享内存断开成功。
子进程ID是:7648
shmctl获取共享内存数据结构成功。
建立这个共享内存的进程ID是:7647
该共享内存的大小为:32
自共享内存中读取的信息为:“我是写入共享内存的测试数据”。
最后一个操作该共享内存的进程ID是:7647
shmdt共享内存断开成功。
shmctl删除共享内存及其数据结构成功。
***********************************************************/
发表评论
-
Linux进程间通信(IPC)
2009-11-07 21:26 1225Linux进程间通信(IPC) 一、管道: 1. 无 ... -
指针和引用操作符的区别
2009-08-17 09:06 1729指针和引用是相似的概念,但并不是相同的。它们都是指向一个对 ... -
大端与小端存储模式详解
2009-08-14 09:03 1697端模式(Endian)的这个词出自Jonathan Swi ... -
memmove 和 memcpy的区别
2009-08-14 09:02 1456memcpy和memmove()都是C语言中的库函数,在头 ... -
malloc()与 alloc()区别
2009-08-14 09:01 1587C语言跟内存分配方式 ... -
五大内存分区--堆、栈、自由存储区、全局/静态存储区和常量存储区
2009-08-14 09:00 1999在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、 ... -
内核中工作队列(linux工作队列)
2009-08-14 08:58 4522Linux自从2.6.20之后,工作队列发生了一些变化,目 ... -
STL中: string、vector、list、deque、set、map 的区别
2009-08-14 08:55 3121在STL中基本容器有: strin ...
相关推荐
Linux 消息队列 Linux 消息队列是一种进程间通信机制,允许不同的进程之间进行数据交换。它由一个标识符和一个队列组成,标识符用于唯一标识消息队列,队列则用于存储要传输的数据。 在 Linux 系统中,消息队列是...
Linux消息队列是一种进程间通信(IPC)机制,允许不同进程之间传递数据。它不同于管道、套接字或共享内存,因为消息队列提供了异步通信的可能性,即发送方不必等待接收方立即处理消息。在Linux内核中,消息队列作为...
Linux消息队列是一种在进程间通信(IPC)中使用的机制,它允许进程向队列中写入消息,然后由其他进程读取。Linux系统继承了System V的IPC机制,其中包括消息队列、信号量和共享内存。消息队列是线性数据结构,每个...
标题"msg_creat.rar_LINUX消息队列_linux 消息队列_linux 消息队列_消息队列"和描述"生成一个消息队列,同时向该消息队列发送一串信息"指向的核心概念是创建和使用Linux的消息队列。 在Linux中,消息队列由内核管理...
在Linux操作系统中,消息队列是一种非常重要的进程间通信(IPC, Inter-Process Communication)机制。消息队列允许进程之间通过消息传递数据,提供了一种可靠且高效的数据交换方式。本教程将深入探讨Linux环境下的...
在Linux操作系统中,消息队列是一种非常重要的进程间通信(IPC,Inter-Process Communication)机制。消息队列允许一个进程发送消息给另一个进程,并且这些消息会被存储在一个内核管理的数据结构中,直到接收进程...
### Linux消息队列分析及应用 #### 一、消息队列基本概念 消息队列(Message Queue)作为Unix系统V版本中的三种进程间通信(Inter-Process Communication, IPC)机制之一,其他两种分别是信号量(Semaphores)和...
Linux消息队列是一种高效、可靠且灵活的进程间通信(IPC)机制,允许不同进程之间交换数据。在标题“linux消息队列测试”中,我们可以理解这是一个针对Linux系统中的消息队列功能进行验证和性能测试的程序。描述指出...
linux 消息队列 发送端简单使用
Linux消息队列实现sample msg_flags = IPC_CREAT|IPC_EXCL; msg_id = msgget(key, msg_flags|0x0666); if( -1 == msg_id) { printf("消息建立失败\n"); return 0; } msg_show_attr(msg_id, msg_info);
Linux IPC通信利用消息队列消息机制,多线程通信,字符串处理,链表操作,信号简单处理。消息队列是System V支持一种IPC机制,通过类似链表的操作向一个FIFO里通过msgsnd发送用户自定义数据,进程可以通过msgrcv来...
在Linux操作系统中,消息队列是一种非常重要的进程间通信(IPC, Inter-Process Communication)机制。它允许进程之间通过共享消息来传递数据,而无需直接访问对方的内存或文件。本示例代码提供了服务器和客户端的...
Linux IPC通信利用消息队列消息机制,多线程通信,字符串处理,链表操作,信号简单处理。消息队列是System V支持一种IPC机制,通过类似链表的操作向一个FIFO里通过msgsnd发送用户自定义数据,进程可以通过msgrcv来...
本资源“Linux--MSMQ-.rar”聚焦于将微软的消息队列服务(Message Queuing,简称MSMQ)的概念应用于Linux环境,为开发者提供了在Linux平台上实现类似功能的指导。 MSMQ是微软提供的一种服务,主要用于Windows系统中...
本文将深入探讨Linux消息队列的原理、使用以及在`msg.tar.gz_linux`压缩包中提供的`client.c`和`server.c`示例代码。 **1. Linux消息队列概述** Linux消息队列是内核管理的一种特殊文件,它允许进程存储和检索消息...
《Linux环境进程间通信(三):消息队列.doc》详细阐述了消息队列的使用,包括如何创建、发送、接收和控制消息队列。《Linux环境进程间通信(五):_共享内存(上).doc》则介绍了共享内存,这是一种效率极高的通信方式,...
综上所述,"msg.rar_linux 消息队列_linux msgrcv_msg_消息队列"的压缩包提供了学习和实践Linux消息队列通信机制的实例代码,通过对msgsnd.c和msgrcv.c的分析和运行,读者可以深入理解消息队列的工作原理和使用方法...
在Linux操作系统中,消息队列是一种进程间通信(IPC,Inter-Process Communication)机制,允许进程之间传递数据。本文将详细解析标题“linux消息队列使用示例”中涉及的知识点,并通过描述中的简单示例代码来理解...
在Linux操作系统中,消息队列是一种非常重要的进程间通信(IPC)机制,它允许不同进程之间传递结构化数据。这个“linux下消息队列例程源码.zip”压缩包很可能包含了一些示例代码,用于演示如何在Linux内核环境下使用...