UNIX中的消息 (转)

UNIX中的消息 (转)[@more@]

      unix中的复用消息
 
  System V中的IPC技术是指进程间相互通讯技术。消息队列使用消息队列标识符标识,具有足够权限的任何进程都可以往一个给定消息队列放置消息,并且也可以从队列中读出消息。与一个队列中的每个消息相关联的类型字段可用于标识消息,从而允许多个进程在单个队列上复用消息。
  考虑我行储蓄通存通兑的实现过程,模拟一个服务器进程带多个客户。具体实现过程如下 :
1 .定义一个消息结构:
  typedef struct {
  int pid ;  // 客户进程id
  char  com[6] ;  //  储蓄所所号
  char text[256] ;  //  传输信息
  }Msg ;
  struct tagMsg {
  long mtype ;  // 消息标识符
  Msg msg ; 
  }mymsg ;
2 . 客户向服务器发送mtype = 1的请求,并且让mymsg.msg.pid等于客户进程id,
3 . 服务器处理请求后向消息队列发送消息,并且让mtype 等于客户进程id。
4 . 客户从消息队列读出mtype等于客户进程id的消息。

具体实现过程如下:
//  Msg.h
# include
# include
# include
# include
# include
# define  KEY 23456L
typedef struct {
  int pid ;
  char  com[6] ;
  char text[256] ;
  }Msg ;

// Server.c
file://------------------------
// Date : 2000.12.27
file://------------------------
# include "Msg.h"
int
main(void)
{
  struct tagMsg {
  long mtype ;
  Msg msg ;
  }mymsg ;
  int msgpid ;
  int size,n ;
  long lcom
 
  if((msgpid = msgget(KEY,IPC_CREAT|0x666)) < 0)
  {
  perror("Msgget :") ;
  exit(0) ;
  }
  size = sizeof(struct tagMsg) ;
  memset(&mymsg,0,sizeof(struct tagMsg)) ;

  for (;;) { 
  if((n = msgrcv(msgpid,&mymsg,size,1,0)) < 0)
  {
  perror("Msgrcv :") ;
  exit(0) ;
  } 
  printf("%6.6s  %dn",mymsg.msg.com,mymsg.mtype) ;
  lcom = atol(mymsg.msg.com) ;
  mymsg.mtype = mymsg.msg.pid ;
  switch (lcom) { 
  case  111111 :
  memcpy(mymsg.msg.text,"qqQQQQ",6) ; 
  memcpy(mymsg.msg.com,"999999",6) ;
  break ;
  case  222222 :
  memcpy(mymsg.msg.text,"UUUUUU",6) ;
  memcpy(mymsg.msg.com,"999999",6) ;
  break ;
  case  333333 :
  memcpy(mymsg.msg.text,"ZZZZZZ",6) ;
  memcpy(mymsg.msg.com,"999999",6) ;
  break ;
  default :
  break ;
  } 
  if(( n = msgsnd(msgpid,&mymsg,size,0)) < 0 )
  {
  perror("""Msgsnd :") ;
  exit(0) ;
  }
  }
  return 0 ;
}

// Client.c
file://------------------------
// Date : 2000.12.27
file://------------------------
# include "Msg.h"
int
main(int argc,char **argv)
{
  struct tagMsg {
  long mtype ;
  Msg msg ;
  }mymsg,mymsg1 ;
  int msgpid ;
  int size,n ;
 
  if((msgpid = msgget(KEY,IPC_ALLOC)) < 0)
  {
  perror("Msgget :") ;
  exit(0) ;
  }
  mymsg.mtype = 1 ;
  mymsg.msg.pid = getpid() ;
  memcpy(mymsg.msg.com,argv[1],6) ;
  size = sizeof(struct tagMsg) ;
 
  if((n = msgsnd(msgpid,&mymsg,size,0)) < 0 )
  {
  perror("Msgsnd :") ;
  exit(0) ;
  } 
  memset(&mymsg1,0,sizeof(struct tagMsg)) ;
  sleep(1) ;

  if((n = msgrcv(msgpid,&mymsg1,size,getpid(),0)) < 0)
  {
  perror("Msgrcv :") ;
  exit(0) ;
  } 
  printf("%6.6sn",mymsg1.msg.com) ; 
  printf("%12.12sn",mymsg1.msg.text) ;
  return 0 ;
}

如有错误请指正。
 E-Mail : yahoo.com.cn">crystal_zsp@yahoo.com.cn
 Phone : 0716-6236590
 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-987657/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-987657/

要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块共享内存 shmctl()或者命令行下ipcrm ftok()。它有两个参数,一个是字符串,一个是字符。字符串一般用当前进程的程序名,字符一般用来标记这个标识符所标识的共享内存是这个进程所开辟的第几个共享内存。ftok()会返回一个key_t型的值,也就是计算出来的标识符的值。 shmkey = ftok( "mcut" , 'a' ); // 计算标识符 操作共享内存,我们用到了下面的函数 #include #include #include int shmget( key_t shmkey , int shmsiz , int flag ); void *shmat( int shmid , char *shmaddr , int shmflag ); int shmdt( char *shmaddr ); shmget()是用来开辟/指向一块共享内存的函数。参数定义如下: key_t shmkey 是这块共享内存的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。但是刚才我们的两个进程没有任何关系,所以就用ftok()算出来一个标识符使用了。 int shmsiz 是这块内存的大小. int flag 是这块内存的模式(mode)以及权限标识。 模式可取如下值: 新建:IPC_CREAT 使用已开辟的内存:IPC_ALLOC 如果标识符以存在,则返回错误值:IPC_EXCL 然后将“模式” 和“权限标识”进行“或”运算,做为第三个参数。 如: IPC_CREAT | IPC_EXCL | 0666 这个函数成功时返回共享内存的ID,失败时返回-1。 // shmid开辟共享内存 shmid = shmget( shmkey , sizeof(in_data) , IPC_CREAT | 0666 ) ; shmat()是用来允许本进程访问一块共享内存的函数。 int shmid是那块共享内存的ID。 char *shmaddr是共享内存的起始地址 int shmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式 成功时,这个函数返回共享内存的起始地址。失败时返回-1。 char *head , *pos , head = pos = shmat( shmid , 0 , 0 ); // 允许本进程使用这块共享内存 shmdt()与shmat()相反,是用来禁止本进程访问一块共享内存的函数。 参数char *shmaddr是那块共享内存的起始地址。 成功时返回0。失败时返回-1。 shmdt( head ); // 禁止本进程使用这块内存 此外,还有一个用来控制共享内存的shmctl()函数如下: #include #include #include int shmctl( int shmid , int cmd , struct shmid_ds *buf ); int shmid是共享内存的ID。 int cmd是控制命令,可取值如下: IPC_STAT 得到共享内存的状态 IPC_SET 改变共享内存的状态 IPC_RMID 删除共享内存 struct shmid_ds *buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定。 返回值: 成功:0 失败:-1 shmctl(shmid,IPC_RMID,NULL); 刚才我们的mpaste.c程序中还可以加入这样几句。 struct shmid_ds buf; ... ... shmctl( shmid , IPC_STAT , &buf ); // 取得共享内存的状态 ... ... shmctl( shmid , IPC_RMID , &buf ); // 删除共享内存 注意:在使用共享内存,结束程序退出后。如果你没在程序中用shmctl()删除共享内存的话,一定要在命令行下用ipcrm命令删除这块共享内存。你要是不管的话,它就一直在那儿放着了。 简单解释一下ipcs命令和ipcrm命令。 取得ipc信息: ipcs [-m|-q|-s] -m 输出有关共享内存(shared memory)的信息 -q 输出有关信息队列(me
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值