linux下C语言编程4使用共享内存实现进程间通信_第1页
linux下C语言编程4使用共享内存实现进程间通信_第2页
linux下C语言编程4使用共享内存实现进程间通信_第3页
linux下C语言编程4使用共享内存实现进程间通信_第4页
linux下C语言编程4使用共享内存实现进程间通信_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、共享内存的函数有以下几个:(1)intshmget(key_tkey,intsize,intshmflg),开辟或使用一块共享内存。shmid所指(2)void*shmat(intshmid,constvoid*shmaddr,intshmflg),将参数向的共享内存与当前进程连接。当使用某共享内存时,需要先使用shmat,达成连接。(3Dintshmdt(constvoid*shmaddr),将先前用shmat连接的共享内存与当前进程解除连接。参数shmaddr为shmat返回的共享内存的地址。在完成对共享内存的使用后,需要使用shmdt解除连接。cmd(4Dintshmctl(intshm

2、id,intcmd,structshmid_ds*buf),控制内存的操作。当为IPC_RMID时,删除shmid所指的共享内存。这些函数的表头文件为sys/ipc.h和sys/shm.h,其详细参数请去网上搜索。下面给出一个使用共享内存实现进程间通信的例子:进程A开辟一块新的共享内存,进程修改这个共享内存,进程C打印输出这个共享内存的内容,进程D删除这个共享内存。进程BCD运行的命令格式为:命令共享内存ID,如./output123432。进程A代码如下:intmain()intshmid;shmid=shmget(IPC_PRIVATE,SIZE,IPC_CREAT|0600);if(sh

3、mid0)perror(shmgeterror);exit(1);printf(createsharedmemoryOK.shmid=%d/n,shmid);return0;进程B代码如下:intmain(intargc,char*argv)intshmid;char*shmaddr;if(argc!=2)perror(argcerror/n);exit(1);shmid=atoi(argv1);shmaddr=(char*)shmat(shmid,NULL,0);if(int)shmaddr=-1)perror(shmaterror./n);exit(1);strcpy(shmaddr,he

4、llo,world!);shmdt(shmaddr);return0;进程CODOO:intmain(intargc,char*argv)intshmid;char*shmaddr;if(argc!=2)printf(argcerror/n);exit(1);shmid=atoi(argv1);shmaddr=(char*)shmat(shmid,NULL,0);if(int)shmaddr=-1)perror(shmaterror./n);exit(1);printf(%s/n,shmaddr);shmdt(shmaddr);return0;进程DODOO:intmain(intargc,c

5、har*argv)intshmid;if(argc!=2)perror(argcerror/n);exit(1);shmid=atoi(argv1);shmctl(shmid,IPC_RMID,NULL);return0;linux下C语言编程5-多线程编程Linux系统下的多线程遵循POSIX线程接口,称为需要使用头文件pthread.h,编译需要在后面加pthread。编写Linux下的多线程程序,-lpthread。关于多线程,主要有以下几个过程:1,创建线程2,各个线程的执行3,等待线程的结束涉及的线程函数主要有:1,intpthread_create(pthread_t*restri

6、cttidp,constpthread_attr_t*restrictattr,void*(*start_rtn)(void),void*restrictarg);函数有4个参数:第一个参数为指向线程标识符的指针。三个参数是一个函数指针(有关函数指针,看这里一个参数是函数指针所需要的参数。第二个参数用来设置线程属性。第),指向线程运行函数的起始地址。最后注意:pthread_create函数返回这些参数做成某个结构体,作为第到第4个参数中。0表示成功。另外如果函数指针需要多个参数的话,就将4个参数。如果有返回值的话,也可将返回值的指针回写pthread_exit()用于线程退出,可以指定返回值

7、,2,pthread_join()等待一个线程的结束。以便其他线程通过pthread_join()函数获取该线程的返回值。线程的应用:并行数据库的查询假设我们有3台计算机A,B,C,每台均安装PG数据库,通过网络连接。我们可以通过多线程将查询SQL广播出去,A,B,C并行查询,最终返回各自的结果。如果没有多线程,而只是用了个循环,那么我们获取结果的过程将是顺序的,即等A的结果返回后才能查询B,B结束后查询C,效率低下。代码如下:/最多支持MAX个线程#defineMAX16/*多线程*/typedefstructPDthreadchar*host;/IPintport;/端口char*dbna

8、me;/数据库名char*query;/SQLDOvoid*rst;/查询结果PDthread;typedefstructNodesintcount;/实际上的节点数量countrst=(void*)ExecuteQuery(p-host,p-port,p-dbname,p-query);pthread_exit(NULL);returnNULL;/*创建多个线程,1个node对应1个线程*输出:thread,pdthread*输入:node,dbname,query,这些值写到pdthread变量中,传递给函数PDthreadSelect(因为此函数只能有一个参数)*/voidPDthrea

9、dCreate(pthread_tthread,PDthread*pdthread,Nodes*node,char*dbname,char*query)inttmp;inti;PDthread*p;for(i=0;icount;i+)/把Nodes作为PDthread的一部分p=pdthread+i;p-host=node-hosti;p-port=node-porti;p-dbname=dbname;p-query=query;tmp=pthread_create(&threadi,NULL,PDthreadSelect,p);if(tmp!=0)printf(PDthreadCreate:

10、线程dd建失败!/n,i);elseprintf(PDthreadCreate:线程d被创建/n,i);voidPDthreadWait(pthread_tthread,intcount)/等待线程结束inti;for(i=0;irstreturn0;编译命令:gcc-I/usr/local/pgsql/include-othth.c-L/usr/local/pgsql/lib-lpq-lpthread,因为使用了libpq库。Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现(Linux环境下C编程指南)Linux环境下C编程指南,通过共享内存进行进程间通信的例子,进程间同步

11、使用信号量来实现。使用说明:这是一个简单的服务器和客户端程序,如果启动程序时不带参数,则执行服务器程序;如果带参数,则执行客户端程序,所带参数只有一个,就是服务器端所显示的共享内存的引用ID。实现原理:服务器端启动后,创建信号量和共享内存,并将共享内存的引用ID显示出来,将信号量的引用ID存放在共享内存中。客户端启动后,利用服务器端提供的内存共享ID将共享内存附加到地址段,读取信号量以实现两个进程之间的同步。之后,这两个进程就可以利用共享内存进行进程间通信,客户端输入的信息将在服务器端显示出来。#include#include#include#include#include#include#i

12、nclude#include#include#defineSHMDATASIZE1000#defineBUFFERSIZE(SHMDATASIZE-sizeof(int)#defineSN_EMPTY0#defineSN_FULL1intdeleteSemid=0;unionsemunintval;structsemid_ds*buf;unsignedshortint*array;structseminfo*_buf;voidserver(void);/不加参数时执行voidclient(intshmid);voiddelete(void);voidsigdelete(intsignum);v

13、oidlocksem(intsemid,intsemnum);voidunlocksem(intsemid,intsemnum);voidwaitzero(intsemid,intsemnum);voidclientwrite(intshmid,intsemid,char*buffer);intsafesemget(key_tkey,intnsems,intsemflg);intsafesemctl(intsemid,intsemnum,intcmd,unionsemunarg);intsafesemop(intsemid,structsembuf*sops,unsignednsops);in

14、tsafeshmget(key_tkey,intsize,intshmflg);void*safeshmat(intshmid,constvoid*shmaddr,intshmflg);intsafeshmctl(intshmid,intcmd,structshmid_ds*buf);intmain(intargc,char*argv)if(argc2)server();elseclient(atoi(argv1);return0;voidserver(void)unionsemunsunion;intsemid,shmid;void*shmdata;char*buffer;semid=saf

15、esemget(IPC_PRIVATE,2,SHM_R|SHM_W);deleteSemid=semid;atexit(&delete);/当程序终止执行时,执行delete函数signal(SIGINT,&sigdelete);/接收到信号SIGINT则执行sigdelete函数sunion.val=1;safesemctl(semid,SN_EMPTY,SETVAL,sunion);sunion.val=0;safesemctl(semid,SN_FULL,SETVAL,sunion);shmid=safeshmget(IPC_PRIVATE,SHMDATASIZE,IPC_CREAT|S

16、HM_R|SHM_W);shmdata=safeshmat(shmid,0,0);safeshmctl(shmid,IPC_RMID,NULL);/删除共享内存,当所有附加该共享内存的进程结束或断开与该共享内存的连接时才执行*(int*)shmdata=semid;buffer=shmdata+sizeof(int);printf(ServerisrunningwithSHMid*%d*n,shmid);while(1)printf(Waitinguntilfull.);fflush(stdout);locksem(semid,SN_FULL);printf(done.n);printf(Me

17、ssagereceived:%s.n,buffer);unlocksem(semid,SN_EMPTY);voidclient(intshmid)intsemid;void*shmdata;char*buffer;shmdata=safeshmat(shmid,0,0);semid=*(int*)shmdata;buffer=shmdata+sizeof(int);semid);printf(Clientoperational:shmidis%d,semidis%dn,shmid,while(1)charinput3;printf(nnMenun1.sendamessagen);printf(

18、2.Exitn);fgets(input,sizeof(input),stdin);switch(input0)case1:clientwrite(shmid,semid,buffer);break;case2:exit(0);break;voiddelete(void)printf(nMasterexiting;deletingsemaphore%d.n,deleteSemid);if(semctl(deleteSemid,0,IPC_RMID,0)=-1)printf(Errorreleasingsemaphore.n);voidsigdelete(intsignum)exit(0);vo

19、idlocksem(intsemid,intsemnum)structsembufsb;sb.sem_num=semnum;sb.sem_op=-1;sb.sem_flg=SEM_UNDO;safesemop(semid,&sb,1);voidunlocksem(intsemid,intsemnum)structsembufsb;sb.sem_num=semnum;sb.sem_op=1;sb.sem_flg=SEM_UNDO;safesemop(semid,&sb,1);voidwaitzero(intsemid,intsemnum)structsembufsb;sb.sem_num=sem

20、num;sb.sem_op=0;sb.sem_flg=0;safesemop(semid,&sb,1);voidclientwrite(intshmid,intsemid,char*buffer)printf(Waitinguntilempty.);fflush(stdout);locksem(semid,SN_EMPTY);printf(done.n);printf(EnterMessage:);fgets(buffer,BUFFERSIZE,stdin);unlocksem(semid,SN_FULL);intsafesemget(key_tkey,intnsems,intsemflg)i

21、ntretval;if(retval=semget(key,nsems,semflg)=-1)printf(semgeterror:%s.n,strerror(errno);exit(254);returnretval;intsafesemctl(intsemid,intsemnum,intcmd,unionsemunarg)intretval;if(retval=semctl(semid,semnum,cmd,arg)=-1)printf(semctlerror:%s.n,strerror(errno);exit(254);returnretval;intsafesemop(intsemid,structsembuf*sops,unsignednsops)intretval;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论