Linux内核与编程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Linux内核与编程·厦门大学软件学院实验三使用Linux高级IPC陈毅东Linux内核与编程厦门大学软件学院提纲结束•进程间通信概述•目标问题——哲学家进餐问题–问题描述–错误与不好的解法–并行度较高的解法•Linux高级IPC机制–概述–SystemV信号灯–SystemV共享内存区•实现的其他问题•实习题Linux内核与编程厦门大学软件学院进程间通信概述(1):引子#includeunistd.h#includesys/types.hintresult;main(){pid_tpid;result=0;pid=fork();if(pid0)exit(-1);if(pid){pid=fork();if(pid0)exit(-1);if(pid==0){sleep(3);result=result+20;exit(0);}}else{sleep(3);result=result+10;exit(0);}while(wait((int*)0)!=-1);printf(%d\n,result);exit(0);}输出结果是什么?Linux内核与编程厦门大学软件学院进程间通信概述(2)•进程是相互独立的,进程间的通信需要专门的机制。•进程之间的通信可以经由文件系统,但实际使用较为复杂(例如,需要锁机制)。•UNIXIPC(InterProcessCommunication)机制是各种进程通信方式的统称。•Linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。Linux内核与编程厦门大学软件学院进程间通信概述(3)•对于UNIX的发展,贝尔实验室和BSD在进程间通信方面的侧重点有所不同:–贝尔实验室对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“SystemVIPC”,通信进程局限在单个计算机内;–BSD则主要考虑跨计算机的进程间通信,形成了基于套接口(socket)的进程间通信机制。Linux内核与编程厦门大学软件学院进程间通信概述(4)返回最初的UNIXIPCSystemVIPC基于Socket的IPCLinuxIPCPOSIXIPC•最初的UnixIPC:信号、管道、FIFO;•SystemVIPC:消息队列、信号量、共享内存区;•POSIXIPC:消息队列、信号量、共享内存区。Linux内核与编程厦门大学软件学院哲学家进餐问题的描述•五个哲学家围坐在一张圆桌周围,每个哲学家面前都有一碗米饭,相邻的两碗之间有一支筷子(如图)。•哲学家的生活包含两种活动:即吃饭和思考。当一个哲学家觉得饿时,他就试图分两次去取他左边和右边的筷子,每次拿起一支,但不分次序。如果成功地获得了一双筷子,他就开始吃饭,吃完以后放下筷子继续思考。这样,问题就是,为每个哲学家写一段程序来描述其行为,要求不死锁。返回Linux内核与编程厦门大学软件学院错误与不好的解法(1)•解法一:可能进入“死锁”状态#defineN5voidphilosopher(inti){while(TRUE){think();take-chopstick(i);take-chopstick((i+1)%N);eat();put-chopstick(i);put-chopstick((i+1)%N);}}若每个哲学家进程都运行到此句后发生进程切换,则进入死锁。Linux内核与编程厦门大学软件学院错误与不好的解法(2)#defineN5voidphilosopher(inti){while(TRUE){think();do{take-chopstick(i);if(can-take-chopstick((i+1)%N))break;elseput-chopstick(i);}while(TRUE);eat();put-chopstick(i);put-chopstick((i+1)%N);}}•解法二:可能进入“饥饿”状态不妨假设此函数能做到“测试且设置”。这种解法可能会造成下面情况:哲学家们不断地重复“拿起各自左边的筷子又放下”的动作,谁也不能进餐。注意:这时和解法一的状态不同,这时进程都没有阻塞。Linux内核与编程厦门大学软件学院错误与不好的解法(3)#defineN5typedefintsemaphore;semaphoremutex=1;voidphilosopher(inti){while(TRUE){think();down(mutex);take-chopstick(i);take-chopstick((i+1)%N);eat();put-chopstick(i);put-chopstick((i+1)%N);up(mutex);}}返回•解法三:可行但效率低下本解法从理论上可行,但从实际角来看,有一局限性:同一时刻只能有一位哲学家进餐。而这里有五支筷子,实际上应能允许两位哲学家同时进餐。Linux内核与编程厦门大学软件学院并行度较高的解法(1)#defineN5#defineLEFT(i+N-1)%N#defineRIGHT(i+1)%N#defineTHINKING0#defineHUNGRY1#defineEATING2typedefintsemaphore;intstate[N];semaphoremutex=1;semaphores[N];voidphilosopher(inti){while(TRUE){think();take-chopsticks(i);eat();put-chopsticks(i);}}Linux内核与编程厦门大学软件学院并行度较高的解法(2)返回voidput-chopsticks(inti){down(&mutex);state[i]=THINKING;test(LEFT);test(RIGHT);up(&mutex);}voidtest(i){if(state[i]==HUNGRY&&state[LEFT]!=EATING&&state[RIGHT]!=EATING){state[i]=EATING;up(&s[i]);}}voidtake-chopsticks(inti){down(&mutex);state[i]=HUNGRY;test(i);up(&mutex);down(&s[i]);}Linux内核与编程厦门大学软件学院概述•SystemVIPC包含了三种机制,在实现“哲学家进餐问题”时,我们只使用信号灯机制和共享存储区机制。主要的函数如下:信号灯共享内存区头文件sys/sem.hsys/shm.h创建或打开IPCsemgetshmget控制IPC操作semctlshmctlIPC操作函数semopshmat,shmdt•SystemVIPC对象以key_t类型的值作为其名字。•SystemVIPC对象以一定的存取权限来控制其访问。返回Linux内核与编程厦门大学软件学院SystemVIPC的名字•SystemVIPC是有名的,这样可以支持无亲缘关系的进程访问同一的IPC对象。其名字的类型为key_t,可以由ftok函数赋予或直接取值IPC_PRIVATE。•ftok函数–原型:#includesys/types.h#includesys/ipc.hkey_tftok(constchar*pathname,intid);–功能:把已存在的路径名和一整数标识符转换成一个key_t值,称为IPC键。–返回值:成功时返回IPC键,出错返回-1。–说明:1、ftok产生的键值不会是IPC_PRIVATE;2、不能保证ftok生成的键值唯一;3、用于产生键的文件不能在该IPC对象存活其内删除。返回Linux内核与编程厦门大学软件学院SystemVIPC对象的存取权限•为防止共享的IPC对象被非法访问,必须为IPC对象设置存取权限。•SystemVIPC对象的存取权限和文件系统中文件的存取权限类似,也用9位分3组表示,三组分别代表属主、组成员和其他用户对该IPC对象的存取权限;每组中三位,只用其中的两位表示是否可读和是否可写。一般为了安全,在创建IPC对象时应该设置存取权限制为0600,表示仅仅对属主是可读,可写的。返回Linux内核与编程厦门大学软件学院SystemV信号灯•semget•semctl•semop•down和up的实现返回Linux内核与编程厦门大学软件学院semget(1)——函数说明•原型:#includesys/types.h#includesys/ipc.h#includesys/sem.hintsemget(key_tkey,intnsems,intoflag);•功能:创建或打开信号灯集合。•返回值:成功返回非负信号灯标识符,出错返回-1。•说明:1、key是欲创建或打开的信号灯集合的名字;2、nsems指明信号灯集合中包含的信号灯数;3、oflag是一个位信息标志,含两部分信息,即存取权限和控制字段。低9位表示存取权限,控制字段中IPC_CREAT位和IPC_EXCL位的设置情况与参数key共同决定了本调用的操作。Linux内核与编程厦门大学软件学院semget(2)——工作流程if(key==IPC_PRIVATE)创建新信号灯集并返回其id;elseif(与key相关的信号灯集合存在)if((oflag&IPC_CREAT)&&(oflag&IPC_EXCL))返回-1;elseif(访问权限允许)返回与key相关的信号灯集id;else返回-1;elseif(oflag&IPC_CREAT)创建新信号灯集并返回其id;else返回-1;返回Linux内核与编程厦门大学软件学院semctl(1)——函数说明•原型:#includesys/types.h#includesys/ipc.h#includesys/sem.hintsemctl(intsemid,intsemnum,intcmd,unionsemunarg);•功能:对semid标识的信号灯集合进行控制。•返回值:成功返回非负值,出错返回-1。•说明:1、cmd是对信号灯集的控制命令,有GETVAL,SETVAL,GETALL,SETALL,IPC_RMID等,我们只用最后的两个。2、semnum标识该信号灯集中某成员(以0为第一个),仅用于GETVAL,SETVAL等命令。3、arg是可选的,取决于参数cmd,GETALL或SETALL等命令就要用到参数arg。Linux内核与编程厦门大学软件学院semctl(2)——unionsemun•unionsemun的定义为:unionsemun{intval;//仅用于SETVAL命令structsemid_ds*buf;//用于IPC_SET等命令ushort*array;//用于SETALL等命令}•注意,本联合未在出现在任何系统头文件中,因此必须由应用程序声明。返回Linux内核与编程厦门大学软件学院semop(1)——函数说明•原型:#includesys/types.h#includesys/ipc.h#includesys/sem.hintsemop(intsemid,structsembuf*opsptr,size_tnops);•功能:对semid标识的信号灯集合中信号灯进行操作。•返回值:成功返回0,出错返回-1。•说明:1、opsptr是指向结构structsembuf的指针,可以是这种类型的结构数组的头指针。数组的每个元素包含对信号灯集合中一个信号的的操作的信息,从而可实现同时对多信号灯的操作。2、nops指出opsptr指向的结构数组中元素数。Linux内核与编程厦门大学软件学院semop(2)——structsembuf•structsembuf的定义为:structsembuf{shortsem_num;//信号灯号:0,1,…,nsems-1shortsem_op;//信号灯操作:0,0,0shortsem_flg;//操作标识:这里我们只要置

1 / 35
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功