中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
IPC sample
作者:未知 时间:2005-09-13 19:19 出处:ChinaUnix.net 责编:chinaitpower
              摘要:IPC sample

经常有人问IPC的问题,下面是一些简单的例子。有空看看!
System V信号量 
[code:1:4e079536a0]
#define PERMS S_IRUSR|S_IWUSR 

void init_semaphore_struct(struct sembuf *sem,int semnum, 
int semop,int semflg) 

/* 初始话信号灯结构 */ 
sem->sem_num=semnum; 
sem->sem_op=semop; 
sem->sem_flg=semflg; 


int del_semaphore(int semid) 

/* 信号灯并不随程序的结束而被删除,如果我们没删除的话(将1改为0) 
可以用ipcs命令查看到信号灯,用ipcrm可以删除信号灯的 
*/ 
#if 1 
return semctl(semid,0,IPC_RMID); 
#endif 


int main(int argc,char **argv) 

char buffer[MAX_CANON],*c; 
int i,n; 
int semid,semop_ret,status; 
pid_t childpid; 
struct sembuf semwait,semsignal; 

if((argc!=2)||((n=atoi(argv[1]))<1)) 

fprintf(stderr,"Usage:%s number\n\a",argv[0]); 
exit(1); 


/* 使用IPC_PRIVATE 表示由系统选择一个关键字来创建 */ 
/* 创建以后信号灯的初始值为0 */ 
if((semid=semget(IPC_PRIVATE,1,PERMS))==-1) 

fprintf(stderr,"[%d]:Acess Semaphore Error:%s\n\a", 
getpid(),strerror(errno)); 
exit(1); 


/* semwait是要求资源的操作(-1) */ 
init_semaphore_struct(&semwait,0,-1,0); 

/* semsignal是释放资源的操作(+1) */ 
init_semaphore_struct(&semsignal,0,1,0); 

/* 开始的时候有一个系统资源(一个标准错误输出) */ 
if(semop(semid,&semsignal,1)==-1) 

fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a", 
getpid(),strerror(errno)); 
if(del_semaphore(semid)==-1) 
fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a", 
getpid(),strerror(errno)); 
exit(1); 


/* 创建一个进程链 */ 
for(i=0;i if(childpid=fork()) break; 

sprintf(buffer,"[i=%d]-->[Process=%d]-->[Parent=%d]-->[Child=%d]\n", 
i,getpid(),getppid(),childpid); 
c=buffer; 

/* 这里要求资源,进入原子操作 */ 
while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR)); 
if(semop_ret==-1) 

fprintf(stderr,"[%d]:Decrement Semaphore Error:%s\n\a", 
getpid(),strerror(errno)); 

else 

while(*c!='\0')fputc(*c++,stderr); 
/* 原子操作完成,赶快释放资源 */ 
while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR)); 
if(semop_ret==-1) 
fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a", 
getpid(),strerror(errno)); 


/* 不能够在其他进程反问信号灯的时候,我们删除了信号灯 */ 
while((wait(&status)==-1)&&(errno==EINTR)); 
/* 信号灯只能够被删除一次的 */ 
if(i==1) 
if(del_semaphore(semid)==-1) 
fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a", 
getpid(),strerror(errno)); 
exit(0); 

[/code:1:4e079536a0]
SystemV消息队列 
[code:1:4e079536a0]
#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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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); 

[/code:1:4e079536a0]
SystemV共享内存 
[code:1:4e079536a0]
#define PERM S_IRUSR|S_IWUSR 

int main(int argc,char **argv) 


int shmid; 
char *p_addr,*c_addr; 
if(argc!=2) 

fprintf(stderr,"Usage:%s\n\a",argv[0]); 
exit(1); 


if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) 

fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno)); 
exit(1); 

if(fork()) 

p_addr=shmat(shmid,0,0); 
memset(p_addr,'\0',1024); 
strncpy(p_addr,argv[1],1024); 
exit(0); 

else 

c_addr=shmat(shmid,0,0); 
printf("Client get %s",c_addr); 
exit(0); 


[/code:1:4e079536a0]

 一颗流星 回复于:2003-04-17 15:46:36
哈哈,太好了,结合实例理解加深不少呢!
我自己编程实现的都是单个进程间的:)

 蓝色键盘 回复于:2003-04-17 16:00:00
SYSTEM V MSG


请求方程序
[code:1:ebf2406b93]
static struct msgbuf1{ 

long mtype; 

char mtext[100]; 

} sndbuf, rcvbuf, *msgp ; 

extern int errno; 

main(int argc, char **argv) 

{ 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=& 

sprintf(sndbuf.mtext,"%2.2s",argv[1]); 

printf("输入4位帐号:"); 

scanf("%s",&sndbuf.mtext[2]); 

sndbuf.mtext[6]=0; 

msgp->mtype=666; 

rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0); 

if (rtrn==-1){ 

perror("msgsnd"); exit(-1); 



msgp=& 

fprintf(stderr,"等待后台数据处理进程的回答...."); 

rtrn=msgrcv(msqid,msgp, 100, atoi(argv[1]), 0); 

if(rtrn==-1){ perror("msgrcv"); exit(-1); } 

sscanf(rcvbuf.mtext,"%[^|]|%lf",name,&balance); 

printf("\n姓名=%s\n",name); 

printf("余额=%lf\n",balance); 


[/code:1:ebf2406b93]



服务方程序
[code:1:ebf2406b93]
static struct msgbuf1{ 

long mtype; 

char mtext[100]; 

} sndbuf, rcvbuf , *msgp; 

extern int errno; 

main() 

{ int rtrn, msgqid ; 

char strbuf[100]; 

if ( (msqid = msgget(0x888, IPC_CREAT|0600)) == -1 ){ 

fprintf(stderr, "msgget 888 failed !\n"); exit(-1); 



while(1) { 

msgp=& 

fprintf(stderr,"等待前台进程的请求...."); 

rtrn=msgrcv(msqid, msgp, 100, 666 ,MSG_NOERROR); 

if(rtrn==-1){ perror("msgrcv");exit(-1); } 

msgp=& 

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); } 







[/code:1:ebf2406b93]

 一颗流星 回复于:2003-04-18 09:50:26
我觉得这是个好东东,藏在后面怕有人看不见。所以
UP

 superzhang 回复于:2003-04-18 10:12:31
往上顶一顶,不错,够热心的。

 sz00 回复于:2003-04-25 14:34:07
太好了!
谢谢!
强烈UP!

 walkandsee 回复于:2003-06-07 14:11:10
good,up

 towerjt 回复于:2003-06-08 10:44:32
up

 unixgood 回复于:2003-06-08 14:24:45
sscanf(rcvbuf.mtext,"%[^|]|%lf",name,&balance); 
这句话看不懂,,"%[^|]|%lf",是什么意思噢?

 jsean 回复于:2003-06-12 11:22:11
好!

 lozity 回复于:2005-05-24 14:44:49
msgp=&是什么意思?

 sea_stone 回复于:2005-05-27 12:16:04
不错,不错
学习中

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有