linux下C语言编程4使用共享内存实现进程间通信

上传人:仙*** 文档编号:98030442 上传时间:2022-05-28 格式:DOC 页数:12 大小:103KB
收藏 版权申诉 举报 下载
linux下C语言编程4使用共享内存实现进程间通信_第1页
第1页 / 共12页
linux下C语言编程4使用共享内存实现进程间通信_第2页
第2页 / 共12页
linux下C语言编程4使用共享内存实现进程间通信_第3页
第3页 / 共12页
资源描述:

《linux下C语言编程4使用共享内存实现进程间通信》由会员分享,可在线阅读,更多相关《linux下C语言编程4使用共享内存实现进程间通信(12页珍藏版)》请在装配图网上搜索。

1、linux下C语言编程4-使用共享内存实现进程间通信共享内存的函数有以下几个:(1) int shmget(key_t key, int size, int shmflg),开辟或使用一块共享内存。(2) void *shmat(int shmid, const void *shmaddr, int shmflg), 将参数 shmid 所指 向的共享内存与当前进程连接。当使用某共享内存时,需要先使用shmat,达成连接。(3) int shmdt(const void *shmaddr),将先前用 shmat连接的共享内存与当前进程解除 连接。参数shmaddr为shmat返回的共享内存的地

2、址。在完成对共享内存的使用后,需要使用shmdt解除连接。(4) int shmctl(int shmid, int cmd, struct shmid_ds *buf),控制内存的操作。当cmd为IPC_RMID时,删除shmid所指的共享内存。这些函数的表头文件为 sys/ipc.h和sys/shm.h,其详细参数请去网上搜索。下面给出一个使用共享内存实现进程间通信的例子:进程A开辟一块新的共享内存,进程B修改这个共享内存,进程C打印输出这个共享内存的内容,进程D删除这个共享内存。进程BCD运行的命令格式为:命令共享内存ID,如./output 123432。进程A代码如下:int mai

3、 n()int shmid;shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT | 0600);if (shmid 0)perror(shmget error);exit(1);prin tf(create shared memory OK. shmid=%d/n, shmid);return 0;进程B代码如下:int main (i nt argc, char *argv)int shmid;char *shmaddr;if (argc != 2)perror(argc error/ n); exit(1);shmid = atoi(argv1);shm

4、addr = (char *)shmat(shmid, NULL, 0); if (i nt )shmaddr = -1)perror(shmat error./n); exit(1);strcpy(shmaddr, hello, world!);shmdt(shmaddr);return 0;进程C代码如下:int main (i nt argc, char *argv)int shmid;char *shmaddr;if (argc != 2)prin tf(argc error/ n);exit(1);shmid = atoi(argv1);shmaddr = (char *)shmat

5、(shmid, NULL, 0); if (i nt )shmaddr = -1)perror(shmat error./n); exit(1);printf(%s/n, shmaddr);shmdt(shmaddr);return 0;进程D代码如下: int main (i nt argc, char *argv)int shmid;if (argc != 2)perror(argc error/n);exit(1);shmid = atoi(argv1);shmctl(shmid, IPC_RMID, NULL);return 0;linux下C语言编程5-多线程编程Linux系统下的多

6、线程遵循POSIX线程接口,称为 pthread。编写Linux下的多线程程序,需要使用头文件 pthread.h,编译需要在后面加-lpthread 。关于多线程,主要有以下几个过程:1, 创建线程2, 各个线程的执行3, 等待线程的结束涉及的线程函数主要有:1,int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rt n)(void), void *restrict arg);函数有4个参数:第一个参数为指向线程标识符的指针。第二个参数用来设置线程属性

7、。第三个参数是一个函数指针(有关函数指针,看这里),指向线程运行函数的起始地址。最后一个参数是函数指针所需要的参数。注意:pthread_create函数返回0表示成功。另外如果函数指针需要多个参数的话,就将这些参数做成某个结构体,作为第4个参数。如果有返回值的话,也可将返回值的指针回写到第4个参数中。2,pthread_join()等待一个线程的结束。pthread_exit()用于线程退出,可以指定返回值,以便其他线程通过 pthread_j oin ()函数获取该线程的返回值。线程的应用:并行数据库的查询假设我们有3台计算机A, B, C,每台均安装PG数据库,通过网络连接。我们可以通过

8、多 线程将查询SQL广播出去,A, B, C并行查询,最终返回各自的结果。如果没有多线程,而 只是用了个循环,那么我们获取结果的过程将是顺序的,即等A的结果返回后才能查询 B,B结束后查询C,效率低下。代码如下:/最多支持 MAX个线程#define MAX 16 typedef struct PDthread/*多线程*/char *host; / IPint port; /端口char *db name; /数据库名char *query; / SQL语句void *rst; /查询结果 PDthread ;typedef struct Nodesint count; /实际上的节点数量

9、cou ntrst = (void *)ExecuteQuery(p-host, p-port, p-db name, p-query);pthread_exit(NULL);return NULL; /* 创建多个线程,1个node对应1个线程* 输出:thread, pdthread *输入:node, dbname, query,这些值写到 pdthread 变量中,传递给函数 PDthreadSelect (因为此函数只能有一个参数)*/void PDthreadCreate (pthread_t thread, PDthread *pdthread, Nodes *node, cha

10、r*db name, char *query)int tmp;int i;PDthread *p;for (i=0; ico unt; i+)/把Nodes作为PDthread的一部分p = pdthread + i;p-host = no de-hosti;p-port =no de-porti;p-db name = dbn ame;p-query=query;tmp = pthread_create(&threadi, NULL, PDthreadSelect, p);if (tmp != 0) printf(PDthreadCreate:线程 4创建失败!/n, i);else pri

11、ntf(PDthreadCreate:线程 d被创建 /n”,i);void PDthreadWait (pthread_t thread, int count)/ 等待线程结束int i;for (i=0; irstreturn 0;编译命令:gcc -l/usr/local/pgsql/in elude -o th th.c -L/usr/local/pgsql/lib -Ipq -Ipthread ,因为使用了 libpq 库。Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现(Linux环境下C编程指南)Linux环境下C编程指南,通过共享内存进行进程间通信的例子,进程

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

13、de #in clude #in clude #i nclude #in clude #defi ne SHMDATASIZE 1000#defi ne BUFFERSIZE (SHMDATASIZE - sizeof(i nt)#defi ne SN_EMPTY 0#defi ne SN_FULL 1int deleteSemid=O;union sem unint val;struct semid_ds *buf;un sig ned short int *array;struct sem info *_buf;void server(void); /不加参数时执行void clie nt

14、(i nt shmid);void delete(void);void sigdelete(i nt sig nu m);void locksem(i nt semid, int semnu m);void uni ocksem(i nt semid, int semnu m);void waitzero(i nt semid, int semnu m);void clie ntwrite(i nt shmid, int semid, char *buffer);int safesemget(key_t key, int n sems, int semflg);int safesemctl(i

15、 nt semid, int semnum, int cmd, union sem un arg);int safesemop(i nt semid, struct sembuf *sops, un sig ned n sops);int safeshmget(key_t key, int size, int shmflg);void *safeshmat(i nt shmid, const void *shmaddr, i nt shmflg);int safeshmctl(i nt shmid, int cmd, struct shmid_ds *buf);int main (i nt a

16、rgc, char *argv)if ( argc 2 )server();elseclie nt(atoi(argv1);return 0;void server(void)union sem un sunion;int semid,shmid;void *shmdata;char *buffer;semid = safesemget(IPC_PRIVATE, 2, SHM_R|SHM_W);deleteSemid = semid;函数atexit (& delete); /当程序终止执行时,执行delete 函数signal(SIGINT, &sigdelete); /接收到信号 SIGI

17、NT 则执行 sigdeletesunion. val = 1;safesemctl(semid, SN_EMPTY, SETVAL, sunion);sunion. val = 0; safesemctl(semid, SN_FULL, SETVAL, sunion);shmid = safeshmget(IPC_PRIVATE, SHMDATASIZE, IPC_CREAT|SHM_R|SHM_shmdata = safeshmat(shmid, 0, 0);safeshmctl(shmid, IPC_RMID, NULL); /删除共享内存,当所有附加该共享内存的进程结束或断开与该共享内

18、存的连接时才执行*(i nt *)shmdata = semid;buffer = shmdata + sizeof( in t);printf(Server is running with SHM id * %d *n, shmid);while(1)prin tf(Waiti ng un til full.);fflush(stdout);locksem(semid, SN_FULL);prin tf(do ne.n);prin tf(Message received: %s.n, buffer);un locksem(semid, SN_EMPTY);void clie nt(i nt

19、shmid)int semid;void *shmdata;char *buffer;shmdata = safeshmat(shmid, 0, 0);semid = *(i nt *)shmdata;buffer = shmdata + sizeof( in t);printf(Client operational: shm id is %d, sem id is %dn, shmid, semid);while(1)char in put3;prin tf(nnMenun 1.se nd a messagen);prin tf(2.Exitn ”);fgets(i nput, sizeof

20、( in put), stdi n);switch(i nput0)case 1: clie ntwrite(shmid, semid, buffer);break;case 2: exit(0);break;void delete(void)printf(nMaster exiting; deleting semaphore %d.n, deleteSemid); if (semctl(deleteSemid, 0, IPC_RMID, 0) = -1 )prin tf(Error releas ing semaphore. n);void sigdelete(int sig num)exi

21、t(0);void locksem(i nt semid, int semnum)struct sembuf sb;sb.sem_ num = semnum;sb.sem_op = -1;sb.sem_flg = SEM_UNDO;safesemop(semid, &sb, 1);void uni ocksem(i nt semid, int semnum)struct sembuf sb;sb.sem_ num = semnum;sb.sem_op = 1;sb.sem_flg = SEM_UNDO;safesemop(semid, &sb, 1);void waitzero(i nt se

22、mid, int semnum)struct sembuf sb;sb.sem_ num = semnum;sb.sem_op = 0;sb.sem_flg = 0;safesemop(semid, &sb, 1);void clie ntwrite(i nt shmid, int semid, char *buffer)prin tf(Waiti ng un til empty.);fflush(stdout);Iocksem(semid, SN_EMPTY);prin tf(do ne.n);printf(Enter Message:);fgets(buffer, BUFFERSIZE,

23、stdi n);uni ocksem(semid, SN_FULL);int safesemget(key_t key, int n sems, int semflg)int retval;if ( (retval=semget(key, n sems, semflg) = -1)prin tf(semget error: %s.n, strerror(err no); exit(254);return retval;int safesemctl(i nt semid, int semnum, int cmd, union sem un arg) int retval;if ( (retval

24、=semctl(semid, semnum, cmd, arg) = -1)prin tf(semctl error: %s.n, strerror(err no); exit(254);return retval;int safesemop(i nt semid, struct sembuf *sops, un sig ned n sops)int retval;if ( (retval=semop(semid, sops, n sops) = -1)prin tf(semop error: %s.n, strerror(err no); exit(254);return retval;in

25、t safeshmget(key_t key, int size, int shmflg)int retval;if ( (retval=shmget(key, size, shmflg) = -1)prin tf(shmget error: %s.n, strerror(errno); exit(254);return retval;void *safeshmat(i nt shmid, const void *shmaddr, i nt shmflg) void *retval;if ( (retval=shmat(shmid, shmaddr, shmflg) = (void *)-1)

26、 prin tf(shmat error: %s.n, strerror(errno); exit(254);return retval;int safeshmctl(i nt shmid, int cmd, struct shmid_ds *buf)int retval;if ( (retval=shmctl(shmid, cmd, buf) = -1)prin tf(shmctl error: %s.n, strerror(errno); exit(254);return retval; atexit语法:#in clude int atexit( void (*fun c)(void);功能:当程序终止执行时,函数调用函数指针func所指向的函数。可以执行多重调用少32个),这些函数以其注册的倒序执行。执行成功返回零值,失败则返回非零值

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!