基于Linux的信号量通信机制研究与实现

系统软件与软件工程本栏目责任编辑:谢媛媛Computer Knowledge and Technology 电脑知识与技术第6卷第12期(2010年4月)基于Linux 的信号量通信机制研究与实现袁玉锦,周群(邯郸学院网络中心,河北邯郸056005)摘要:该文以信号量通信理论为基础,通过对Linux 信号量相关系统调用的分析,着重讨论了内核级和用户级的信号量通信、同一进程内线程之间的通信、多用户的进程间的通信等问题,并采用ANSI C 编写了信号量通信的具体实例。

关键词:信号量;Linux ;多进程通信;线程通信中图分类号:TP316文献标识码:A 文章编号:1009-3044(2010)12-3279-031信号量通信理论操作系统原理中利用信号量来解决多进程互斥访问临界资源的问题,还可来描述多进程之间的前趋关系,即同步问题。

信号量的概念由荷兰学者E.W.Dijkstra 于1965年提出。

信号量实际是一个整数,进程(也可以是线程)在信号量上的操作分2种,一种称为P 操作,另一种称为V 操作。

P 操作是让信号量的值减1,V 操作是让信号量的值加1。

在进行实际的操作之前,进程首先检查信号量的当前值,如果当前值大于0,则可以执行P 操作,否则进程休眠,等待其他进程在该信号量上的V 操作,因为其他进程的V 操作将让信号量的值增加,从而它的P 操作可以成功完成。

某信号量在经过某个进程的成功操作之后,其他休眠在该信号量上的进程就有可能成功完成自己的操作,这时系统负责检查休眠进程是否可以完成自己的操作。

在操作系统中,信号量最简单的形式也是最初被提出时定义的形式是一个整数,多个进程可检查并设置信号量的值。

这种检查并设置(Test-and-Set)操作是不可中断的,也称为“原子”操作。

检查并设置操作的结果是信号量的当前值和设置值相加的结果,该设置值可以是正值,也可以是负值。

根据检查并设置操作的结果,进行操作的进程可能会进入休眠状态,而当其他进程完成自己的检查并设置操作后,由系统检查前一个休眠进程是否可以在新信号量值的条件下完成相应的检查并设置操作。

这样,通过信号量,就可以协调多个进程的操作,实现多进程之间通信。

操作系统原理中通常把信号、信号量通信称为低级通信,而把管道、消息队列、共享存储区通信称为高级通信。

信号量分为有名、无名两种,进程间通信用有名信号量,同一进程内部通信一般用无名信号量。

2Linux 中的信号量从意义和实现机理上,Unix System V 或Linux 的信号量与以上所述的常规信号量没有什么区别,但System V 提供的信号量机制要复杂得多,并且分为两种不同系统调用类型:一种是用内核级的信号量,有关系统调用在/usr/include/semaphore.h 中包含,一般可用于内核级的进程通信和内核级的线程通信;另一种是用户级信号量,有关系统调用在/usr/include/sys/sem.h 中包含,一般可用于多用户进程之间通信。

2.1内核级的信号量相关系统调用int sem_init (sem_t *sem ,int pshared ,unsigned int value)作用:为单个信号量设置初值,第一参数*sem 为指定的信号量对象;第二参数pshared 为共享标志,如值为0表示私有信号量,非0表示可以与其他进程共享的信号量;第三参数value 为要为信号量设置的初值。

相关数据结构如下:struct{struct{long int status ;int spin_lock ;}sem_lock ;int sem_value ;pthread_descr sem_waiting ;}sem_tint sem_wait (sem_t *sem);作用:对指定的信号量进行P 操作。

Int sem_post (sem_t *sem);作用:对指定的信号量进行V 操作。

总结:以上是内核级信号量通信常用到的三个系统调用,使用方式较为简单,但主要适用于内核级多线程之间通信,后面将给出多线程通信的具体实例。

收稿日期:2010-02-21作者简介:袁玉锦(1980-),女,河北曲周人,邯郸学院网络中心,助教,学士,研究方向为计算机网络;周群(1981-),女,河北武安人,助教,学士,主要研究方向为计算机网络。

ISSN 1009-3044Computer Knowledge and Technology电脑知识与技术Vol.6,No.12,April 2010,pp.3279-3281E-mail:xsjl@ Tel:+86-551-569096356909643279Computer Knowledge and Technology电脑知识与技术第6卷第12期(2010年4月)2.2用户级信号量相关系统调用int semget(key_t key,int nsems,int semflg);作用:创建一个新的信号量组或获取一个已经存在的信号量组。

返回值为此信号量组的id,第一参数key是系统内表示此组信号量的名字,其值在系统内必须是唯一的整型数,可以人工给定,也可以通过使用其他系统调用自动产生;第二参数nsems表示要创建的信号量组中包含几个信号量;第三参数表示此信号量组的使用权限,即_rwxrwxrwx方式,使用时采用模数方式,如0777表示所有者、同组人和其他人具有所有权限。

int semop(int semid,struct sembuf*sop,int nsops);作用:可以一次对一个或多个信号量进行P,V操作。

第一参数为由semget()返回的信号量组的id;第二参数为一个较为复杂的数据结构,给sop->sem_op赋负值表示P操作,给sop->sem_op赋正值表示V操作;第三参数nsops表示要对此信号量组中的哪个信号量实施P,V操作。

Int semctl(int semid,int semnum,int cmd,semun arg);作用:可以用来获取一些信号量的使用信息或者对信号量赋初值。

第一参数为由semget()返回的信号量组的id;第二参数为要控制的信号量个数;第三参数为控制命令;第四参数的arg.array用来存放信号量的值。

总结:以上是用户级信号量通信常用到的三个系统调用,使用方式较为复杂,但主要适用于多用户进程之间的通信。

后面将给出2个用户进程通信的具体实例。

3信号量通信实例3.1经典“生产者/消费者”问题这一问题可以描述如下:两个进程共享一个公共的、固定大小的缓冲区。

其中一个进程,即生产者,向缓冲区放入信息,另外一个进程,即消费者,从缓冲区中取走信息(该问题一般也可以化为m个生产者和n个消费者)。

当生产者向缓冲区放入信息时,如果缓冲区是满的,则生产者进入休眠,而当消费者从缓冲区中拿走信息后,可唤醒生产者;当消费者从缓冲区中取信息时,如果缓冲区为空,则消费者进入休眠,而当生产者向缓冲区写入信息后,可唤醒消费者。

以下为主要程序代码,一个线程插入1到10000的整数,另一个线程读取并打印。

void*producer(void*data){for(n=0;n<10000;n++){sem_wait(sem_write);/*P操作*/buffer[writepos]=n;/*在缓冲区中保存一个整数*/writepos++;If(writepos>=BUFFER_SIZE)writepos=0;sem_post(sem_read);/*V操作;表示缓冲区中有数据*/}}void*consumer(void*data){while(1){sem_wait(sem_read);/*P操作*/data=buffer[readpos];/*从缓冲区读取数据*/printf(″-->%d\n″,date);readpos++;if(readpos>=BUFFER_SIZE)b->readpos=0;sem_post(sem_write);}}int main(void){sem_t sem_write,sem_read;/*可读取元素个数和可写入的空位个数*/pthread_t th_a,th_b;/*定义线程对象*/sem_init(sem_write,0,BUFFER_SIZE_1);/*初始化为BUFFER_SIZE_1*/sem_init(sem_read,0,0);/*初始化为0*/readpos=writepos=0;/*初始化为缓冲区读写位置*//*建立生产者和消费者线程。

*/pthread_create(&th_a,NULL,producer,0);pthread_create(&th_b,NULL,consumer,0);/*等待生产者和消费者结束。

*/pthread_join(th_a,&retval);pthread_join(th_b,&retval);}程序首先建立2个线程分别扮演生产者和消费者的角色。

生产者负责将1到10000的整数写入缓冲区,而消费者负责从同一个缓冲区中读取并删除由生产者写入的整数。

因为生产者和消费者是2个同时运行的线程,并且要使用同一个缓冲区进行数据交换,因此必须利用信号量机制实现同步。

起初程序初始化了2个信号量,分别表示可读取的元素数目和可写入的空位个数,并分别初始化为0和缓冲区大小减1。

生产者首先对sem_write进行P操作(即sem_wait调用),看是否能够写入,如果此时sem_write信系统软件与软件工程3280本栏目责任编辑:谢媛媛系统软件与软件工程本栏目责任编辑:谢媛媛Computer Knowledge and Technology 电脑知识与技术第6卷第12期(2010年4月)号量的值大于零,则sem_wait 可以立即返回,否则生产者将在该sem_write 信号量上等待。

生产者在将数据写入之后,在sem_read 信号量上进行V 操作(即sem_post 调用)。

此时如果有消费者等待在sem_read 信号量上,则可以被系统唤醒而继续运行。

消费者线程的操作恰恰相反,首先在sem_read 上进行P 操作,当读取数据并打印后,在sem_write 信号量上进行V 操作。

通过上面的例子可见,System V 或Linux 线程(轻量级进程)之间的信号量通信机制是内核级的,其使用的函数在/usr/include/semaphore.h 中说明。

以上代码经修饰后,可在Linux 下编译运行,编译方式为$gcc -o prod_cons.exe -lpthread prod_cons.c 。

合集下载

linux中的signal机制

linux中的signal机制

Linux支持的信号列表如下。很多信号是与机器的体系结构相关的,首先列出的是POSIX.1中列出的信号:
信号 值 处理动作 发出信号的原因
----------------------------------------------------------------------
break;
case 2:
printf("Get a signal -- SIGINT ");
break;
(对于SIGSYS,SIGXCPU,SIGXFSZ,以及某些机器体系结构下的SIGBUS,Linux缺省的动作是A (terminate),SUSv2 是C (terminate and dump core))。
下面是其它的一些信号
信号 值 处理动作 发出信号的原因
(1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
(2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
(3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
收 到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处 理。第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信 号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。
传递给信号处理例程的整数参数是信号值,这样可以使得一个信号处理例程处理多个信号。系统调用signal返回值是指定信号signum前一次的处理例程或者错误时返回错误代码SIG_ERR。下面来看一个简单的例子:

信号量机制在Linux中的实现

信号量机制在Linux中的实现
维普资讯
20 0 7年第 4期
文章编号 :0 62 7 (0 7 0 -1 1 3 10 - 5 20 )40 2 - 4 0
计 算 机 与 现 代 化 JS A J Y I N A HU IU N I U X A D I A
总第 10期 4
基金项 目: 江西省教育厅教研 课题资助项 目( 教务字 20 第 6 号 ) 04 7 作者简介 : 17 一 , , (9 4 ) 男 江西南 昌人 , 江西师范大学计算 机信 息工程学 院讲师 , 硕士 , 研究方 向 : 作系统 , 操 计算 机 网络 ; 昌 王 晶(98)男 , 17. , 江西南昌人 , 讲师 , , 硕士 研究方 向: 息系统 , 信 形式化方 法。
为经典 的系统 同步 机制进 行介 绍 , 一般 都仅 限于 原 但
理 的阐述 。由于一 种 机 制 的 实现 往 往 涉及 到系 统 的
P V操作是两个对信号量进行操作 的过程 , / 一般
定义 如下 :
poeu (a : m po ) poeu (a ssm po ) r dr P v s e ahr c e r s e r dr V v : a hr c e r e e
0 引 言
中断 嵌套 可能 会破 坏数 据访 问的完 整性 , 可 由 这 中断屏蔽 来避 免 。但多 进程/ 线程对 共享 数据 的访 问
信号量 (e ahr) L u s po 在 i x中是一种 睡 眠锁 。 m e n 如果有一个进程试图获得一个已被 占用的信号量 , 则 信号量会将其推人一个等待队列 。当持有信号量 的 进程将信号量释放时 , 处于等待队列中的进程将被唤 醒, 并获得该信号量。通常情况下 , 信号量的值为 l , 即在一个时刻 , 最多允许一个进程 占有信号量 , 该种 信号量也称为互斥信号量。当然 , 也可将信号量的值 设为大于 l则该种信号量称 为计数信号量。内核 中 , 基本使用互斥信号量 , 计数信号量只在特殊情况下才 会用到 , 本文主要分析的是互斥信号量。

信号量机制解决互斥问题实验报告

信号量机制解决互斥问题实验报告

信号量机制解决互斥问题实验报告一、实验目的本实验旨在通过实际操作,深入理解信号量机制在解决互斥问题中的应用,并掌握其实现原理。

通过实验,我们将观察信号量如何确保对共享资源的互斥访问,从而提高多线程程序的安全性和稳定性。

二、实验环境操作系统:Linux编程语言:C语言开发工具:gcc编译器、终端三、实验原理信号量机制是一种常用的同步原语,用于解决多线程或多进程间的互斥问题。

信号量是一个整数值,通常用于表示资源的数量。

在解决互斥问题时,信号量通过维护一个非负的整数值来确保对共享资源的互斥访问。

四、实验步骤创建两个线程,它们需要访问共享资源。

使用信号量来同步这两个线程,确保它们不会同时访问共享资源。

在访问共享资源之前,线程必须获取信号量。

如果信号量的值为0,线程将被阻塞,直到信号量的值变为正值。

当线程完成对共享资源的访问后,释放信号量,使其值加1。

重复上述步骤,直到完成所有线程的同步操作。

五、实验代码实现以下是一个简单的C语言示例代码,演示了如何使用信号量解决互斥问题:#include <stdio.h>#include <pthread.h>// 定义共享资源数和线程数#define RESOURCE_COUNT 5#define THREAD_COUNT 2// 定义信号量变量pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int semaphore = RESOURCE_COUNT; // 初始化为可用资源数void *thread_func(void *arg) {int i;for (i = 0; i < RESOURCE_COUNT; i++) {pthread_mutex_lock(&mutex); // 获取互斥锁,保护临界区代码printf("Thread %ld is accessing resource %d\n",pthread_self(), i);semaphore--; // 占用一个资源pthread_mutex_unlock(&mutex); // 释放互斥锁,允许其他线程进入临界区代码sleep(1); // 模拟耗时操作}pthread_exit(NULL);}int main() {pthread_t threads[THREAD_COUNT];int i;for (i = 0; i < THREAD_COUNT; i++) {pthread_create(&threads[i], NULL, thread_func, NULL); // 创建线程并执行函数thread_func()}for (i = 0; i < THREAD_COUNT; i++) {pthread_join(threads[i], NULL); // 等待所有线程执行完毕}return 0;}六、实验结果与分析通过运行上述代码,我们可以观察到以下实验结果:在多线程环境下,当一个线程正在访问共享资源时,其他线程将被阻塞,直到资源被释放。

Linux之信号量,比较全面,个人总结。

Linux之信号量,比较全面,个人总结。

信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。

信号量的值为正的时候,说明它空闲。

所测试的线程可以锁定而使用它。

若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。

二.信号量的分类在学习信号量之前,我们必须先知道——Linux提供两种信号量:POSIX信号量又分为有名信号量和无名信号量。

有名信号量,其值保存在文件中, 所以它可以用于线程也可以用于进程间的同步。

无名信号量,其值保存在内存中。

倘若对信号量没有以上的全面认识的话,你就会很快发现自己在信号量的森林里迷失了方向。

三.内核信号量1.内核信号量的构成内核信号量类似于自旋锁,因为当锁关闭着时,它不允许内核控制路径继续进行。

然而,当内核控制路径试图获取内核信号量锁保护的忙资源时,相应的进程就被挂起。

只有在资源被释放时,进程才再次变为可运行。

只有可以睡眠的函数才能获取内核信号量;中断处理程序和可延迟函数都不能使用内核信号量。

count:相当于信号量的值,大于0,资源空闲;等于0,资源忙,但没有进程等待这个保护的资源;小于0,资源不可用,并至少有一个进程等待资源。

wait:存放等待队列链表的地址,当前等待资源的所有睡眠进程都会放在这个链表中。

sleepers:存放一个标志,表示是否有一些进程在信号量上睡眠。

2.内核信号量中的等待队列(删除,没有联系)上面已经提到了内核信号量使用了等待队列wait_queue来实现阻塞操作。

当某任务由于没有某种条件没有得到满足时,它就被挂到等待队列中睡眠。

当条件得到满足时,该任务就被移出等待队列,此时并不意味着该任务就被马上执行,因为它又被移进工作队列中等待CPU资源,在适当的时机被调度。

内核信号量是在内部使用等待队列的,也就是说该等待队列对用户是隐藏的,无须用户干涉。

由用户真正使用的等待队列我们将在另外的篇章进行详解。

3.内核信号量的相关函数(2)申请内核信号量所保护的资源:4.内核信号量的使用例程在驱动程序中,当多个线程同时访问相同的资源时(驱动中的全局变量时一种典型的共享资源),可能会引发“竞态“,因此我们必须对共享资源进行并发控制。

linux sem用法

linux sem用法

linux sem用法Linux系统中的sem(信号量)是一种用于进程间通信和同步的机制。

它提供了一种多个进程之间能够互斥地访问共享资源的方法。

在本文中,我将详细介绍sem的用法,并一步一步地回答您的问题。

第一步:什么是sem?Sem是由Linux内核提供的一种进程同步原语。

它允许进程在对共享资源的访问上进行同步,以避免竞争条件的发生。

它可以用于实现互斥访问共享资源的目的。

第二步:sem的创建和初始化在Linux中,可以使用semget()函数创建一个新的信号量,或者使用semget()函数打开一个已经存在的信号量。

创建新的信号量时,需要指定一个键值,这个键值标识了信号量的唯一性。

创建一个新的信号量的示例代码如下:cint semid = semget(key, 1, IPC_CREAT IPC_EXCL 0666);初始化信号量的值可以使用semctl()函数,其中第二个参数是信号量的编号,第三个参数是命令,第四个参数是信号量的初始值。

初始化信号量的示例代码如下:cunsigned short sem_array[1] = {1}; 初始信号量为1union semun arg;arg.array = sem_array;semctl(semid, 0, SETALL, arg);第三步:sem的P操作和V操作一旦创建和初始化了信号量,就可以使用semop()函数对信号量进行P操作(减法操作)和V操作(加法操作)。

P操作会将信号量的值减1,如果信号量的值为0,则进程将会被阻塞,直到信号量的值大于0为止。

V操作会将信号量的值加1。

如果有多个进程在等待该信号量,则会选择其中一个进行唤醒。

P操作的示例代码如下:cstruct sembuf sb;sb.sem_num = 0;sb.sem_op = -1;sb.sem_flg = SEM_UNDO; semop(semid, &sb, 1);V操作的示例代码如下:cstruct sembuf sb;sb.sem_num = 0;sb.sem_op = 1;sb.sem_flg = SEM_UNDO; semop(semid, &sb, 1);第四步:sem的销毁当信号量不再需要时,可以使用semctl()函数进行销毁。

操作系统实验报告(进程间的共享存贮区和信号量通信)

操作系统实验报告(进程间的共享存贮区和信号量通信)

case -1:perror("fork()");exit(0);case 0:do_child_loop(sem_set_id,FILE_NAME);exit(0);default:break;}}for(i = 0;i<10;i++){int child_status;wait(&child_status);}printf("main is done");fflush(stdout);return 0;}运行结果:二、共享主存段机制共享主存段为进程提供了直接通过主存进行通信的有效手段,不像消息缓存机制那样需要系统提供缓存,也不像pipe机制那样需要事先建立一个特殊文件,而是有通信双方直接访问某些共享虚拟存储器空间。

在系统V中,系统管理一组共享主存段控制块。

通信进程在使用共享主存段以前,首先提出申请,系统为止分配存储空间并返回共享主存段标识号。

一个共享段建立后,进程把它被附加到自己的虚拟存储空间中。

一个进程可以附加多个共享主存段。

一个主存段一旦被附加到进程的虚拟机空间后,对它的访问以其他虚拟机的访问完全相同。

但为了保证共享主存段数据完整性,通信的进程之间要互斥的进行访问。

当通信进程不再需要该共享主存段时,可使用命令将其与进程分离,从而使其进程的虚空间删除。

为了理解进程通过共享主存段的通信过程,下面举例,一个是进程向共享段写信息的例子:一个是进行从共享段读信息的例子。

代码如下:四、实验过程与分析一、信号量机制在第一个例子的程序中创建了5个并发子进程,互斥地对文件进行写操作,将自己的进程号写到文件中去,信号量的初值为1,当地一个进程执行update_file函数时首先将信号量值-1,(相当于P操作)致使其它进程等待无法操作文件,直到其结束后,将其值变为1后(相当于V操作),其它进程并发竞争对文件的写操作,并将自己的pid 写入文件中。

在linux中信号量机制的执行既步骤如下所示:(1)信号量的定义:struct semaphore {spinlock_t lock;unsigned int count;struct list_head wait_list;};在linux中,信号量用上述结构体表示,我们可以通过该结构体定义一个信号量。

优先级继承运用于Linux内核信号量的研究与实现


( hn s e pes me oi oc s a e , a ga g0 5 0 , hn ) C ieeP o l’Ar dP l eF re d my L n fn 6 0 , C ia c Ac 0
A b t a t I s v r m p ra t t ole t e p o e f p irt n e so y m e n ro i ih rt n e wh n sr c : t i ey i o tn o s v h r blm o ro i i v r in b a s ofp i rt n e i c e y y a
k r l a a s st ets nt m b d e y tm PCM 一 3 0 ene, ndp se h e t e o he e d d s se of 35.
Ke wo d : r r v rin p ir h r a c ; e p oe ra— me e e d ds s m y r s p i i i eso ; roi i e i n e sma h r;e li ; mb d e yt ot n y y t n t t e
.
sma h r p rt n hsp p rraie h ae p ir n ei n e poo o y mo i ig te L n x e p oe o eai ,ti a e e l ste b s roi ih r c r tc l df n h iu o z y t a t b y
~
析 内核信 号量操作源代码 的基 础上 ,基于实时应 用实 现 基本优 先级继承协议 。
d wn f i d) o —al ( e 操作 函数 进入 深度 睡眠状 态 。函数 d wn f i d) o —al ( e 的作 用是通过 调 用函数一d wn) o ( 实

linux信号量实现原理

linux信号量实现原理【导言】Linux作为开源操作系统,在程序设计和开发方面广泛应用。

而信号量Semaphore作为进程同步和互斥的一种机制,在Linux系统中也广泛使用,特别是在多进程编程中。

本文将从概念、原理、实现等方面为读者深入解析Linux信号量的实现原理。

【正文】一、信号量的概念信号量是一种进程同步机制,用于解决多个并发进程或线程的访问共享资源带来的问题。

它是由E.W. Dijkstra在发明了PV操作之后,发明的一种机制,意味着操作系统的发展。

二、信号量的原理Semaphore本身是一个计数器,用于记录可用资源的数量,资源数量非0即1。

在Linux系统中,信号量一般由一个整数和两个操作——PV操作组成。

P操作,称为down操作,表示试图获取资源,如果可用资源的数量大于0,则占用该资源并将可用资源的数量减1;否则阻塞等待。

V操作,称为up操作,表示释放资源,增加可用资源的数量。

信号量使用可有效避免多个进程、线程对共享资源的相互影响,实现了多个进程之间的同步和互斥,从而保证了系统的稳定性和性能。

三、信号量的实现Semaphore实现主要分为两种:System V IPC信号量和POSIX IPC信号量。

System V IPC信号量是最早开发实现的方法,主要是使用semget、semctl、semop三个函数实现。

而POSIX IPC信号量则相对较新,主要是使用sem_init、sem_destroy、sem_wait、sem_post四个函数实现。

System V IPC信号量的实现需要操作系统调用内核,在一定程度上增加了系统的负担,从而影响了系统的性能和稳定性。

而POSIX IPC信号量则更加灵活、高效、可移植。

四、应用实例Semaphore的应用广泛,可以在多进程、多线程编程、操作系统调度、交通管制等方面使用。

在Linux系统中,Semaphore常常用于控制多个进程对共享文件、共享内存的读写访问,避免产生竞争条件,提高了程序执行效率。

LINUX内核进程高效通信机制研究

8)
摘要 :进程 间的通信是 多任务 、多用户操作 系统 必须考虑 的重 大问题 ,L u i x继承 了 U i的基本设计 思想,其 n n x 安全性和稳定性得到 了人们 的认 可,但 随着其应用领 域的不断拓展 ,其通信机制 已经不能满足用 户的 需求。本 文在
分析 Ln x内核进程 通信机制 的基础上 ,就如何提 高 Ln x内核进程 间的通信效能进行 了研 究。 iu iu 关键词 : Ln x操作 系统 ;内核进程 ;高效通信息 ;优化措施 iu
中图分 类号:T 31 2 P 1. 5
一
文献标识码 :A 文章编号 :10- 59( 1) 8 0 1- 2 07 99 2 2 0- 18 0 0
引言 程之间是分离的任务 , 各个进程有着 自己的权利和责任, 何 任 L n x 是一种 可运行 于多种平 台的,源代码公 开的 多任 iu 个进程崩溃 了,不应该影响到其它进程导致其它进程崩溃 , 每个独立 的进程都运行在 自己的虚拟地址空 间之 中。 务、多用户操 作系统,Ln x继承 了 U i iu n x的基 本设计 思想 , 在安全性 和稳定性方面得到了大量使用者的认可, 于这种 多 对 三 、L u x内核进程通信手段分类 i n L n x 内核进程通信 所采用 的通 信机制 ,基本上 是延用 iu 任 务、多用户 的操 作系统,其 内核进程 间的通信 可以说是整个 系统的核心要素 , 是保证 其它子系统能获得 相应 的系统资源得 U I N X平台所采 用的进程通信机制 ,其 中,A & T T的 贝尔实验室 以正常运行的根本 。 近年来 , 随着 L n x系统的应用领域的不 和 加州大学伯 克利分校 的伯 克利软件发 布中心在进程 通信机 iu 断拓展 , 基于 L n x系统的应用软件不断增多 , iu 使得系统负荷 制方面 的侧 重点并不相同,贝尔实验 室在对 U I N X早期进程 间 不断加重 , 虽然 L n x操作系统提供 了多种进程通信机制 , iu 但 通 信手段改进和扩充的基 础上,形成了 “ y t m V P ”通信 S s e I C 这些通信机制在承担大容量数据传输时效率较差 , 已经不能满 机制,该通信机制将通信进程局 限于单个计 算机 内,而伯 克利 足用户 日益增长 的需求 , 如何针对 L n x系统进程通信机制 的 软件发布中心则跳过了单个计算机 的限制,形成 了 S c e iu o k t进 L nx在继承两者 的基础上 , 提供 了管道 、 号、 信 不足进行 改进 , 立高速有 效的通信机制 , 为 L n x系统应 程通信机制 。 iu 建 成 iu 跟踪 、命名管道、报 文、共享 内存、信号量 以及插 口等通信手 用所必须 关注 的问题 。下面 , 本文在分析 L n x内核进程通信 iu 机制 的基础 上, 就如何提 高 L n x内核进程 间的通信效 能进行 段 。其中 ,管道、信号 、跟踪通信手段属于 “ y tm V P ” iu S s e IC 探 讨。 通信机制 ,而其余几种通信手段则属于 S c e 通 信机 制。 o kt 二 、L nX内核 结 构 组 成 iU 管道 通信机制 是通 过在父子 进程间或者 兄弟进程 间通过 进 程实质上就是处于执行状态的程序, 并不仅 限于 程序 系统 调用建立一个 单 向的通信 管道来实现进 程通信 的通信机 但 代 码,通常还包括其它 资源如打 开的文件 、处理器状态 、地址 制 。 这种管道路是 由父进程所建立的 , 对子进程 来说 是静 态的 , 空间、存放全局变量的数据段等。L n x系统下的进 程应 当包 是采用先入先 出的原则来进行进程 间内容 的传递 , iu 其每个 管道 含一段可执行程序 、专用 的系统堆栈空间、进程控制块 、独立 都是 单向的,因此要实现双 向通信就需要建立两个 管道。信号 的存储空间几个要素 。L n x建立这种基于多用户、多任务的 通信机制严格 的来说并不是 为进程 间通信而设 置的, 也用 于 iu 但 大型应用系统 ,主要是倾向于通过大型、复杂 、孤立的进程来 进程 间的通信 ,这种通信机制更多 的偏 向于 “ 中断 ” 机制 的软 提供应用功 能, 了真正实现 多任务 、 为 多用户应用环境 , iu 件模拟 ,一般将信 号发送者作 为中断源 ,接 受者作为处理器 , Lnx 充分利用 了任务切换机制 , 从而有效 的降低 了对硬件配置的要 采 用 发送 中 断 请求 的 方式 来 实现 通 信 。跟 踪 是通 过 调 用 求, 并支持多种处理器芯片 , 但严格来说 L n x并不是实时操 p r cO 读写其它子进程地址空间中的 内容的方法 , 来实现 iu tae 作系统 , 因此要提高其实时性能 , 必须从其进 程调度策 略入 手, 跟踪子进 程执行的 目的。这几类进 程通 信机制,都只能应用于 提 高其通信效能 ,从 而改进其 实时 陛。 父进程和子进 程之间,或者兄弟进 程之 间,在发送信号时需要 L n x内核主要分为进程调度 、 iu 内存管理 、 拟文 件系统、 对方的 P D 整个通信 管道对于 子进程来 说是 静态的, 向的, 虚 I, 单 网络接 口、进程 间通信 五个子 系统 。进程 调度控制进程对 C U 在实际使用中通常还需要在建立动态通信管道来辅助通信 。 P 的访 问,当需要进行下一个进程 时, 进程设度程序 即依据需求 命名管道是采用 F F I O文件 的形式存在于文件系统之 中, 选择最值得运行 的进程 。可运特进程 则是等 待 C U资源程 , P 当进程间需要通信时,通过使用其文件名来打开管道 , 因此管 L n x所采 用 的进程 调度算 法是这种基 于优先级 的简单 的算 道的使用不再局限于近亲进程之间 。 iu 报文队列通信机制是通过 法。 在五个子 系统 之间关系十分密切 , 进程调度承担控制与沟 系统调用设立一个报文 队列 , 进程通过系统调用 向该 队列发送 通 的作 用,当存在 多个 程序 时, 程序要获取 C U资源运行就 必 消 息或从队列 中接 收消息 ,以报 文传递 的形式来 实现 进程通 P 须 为该程序创 建进程 , 而创建进程首先就 必须将程序和相关数 信 。 共享 内在是通过系统调用为进程设立共享 内存 区, 其它进 据 写入 内存 之中。进程 间的通信 主要依靠内存 管理来进 行,依 程通过系统调用将 该内存 区映射 到用户地址空 间中, 即可像正 靠共 享内存通信机制, 允许 两个 进程 除了拥有 自己的私 有内存 常内存访 问一样读 写该共享 内存 区。 虽然共享 内存通信机制快 外 , 可以存 取共 同的内存区域。虚拟文件子系统是利用网络 速有 效, 还 但共享 内存通信机制不像其它通信机制那样 能够在 写 接 口支持 网络文件 的系 统 ,该系 统也 同样依靠 内存管理 的支 入后就立 即唤醒睡 眠等待 中的进程 , 因此需要与其它通信机制 持 ,来实现虚拟 文件系统的进程交换, 程的交换 由调度程 序 相配合使用 。 进 来 定期进 行调度 ,因此 内存管理需要依赖于进程调度 。 四、进 程通信 机制对 比分析 可 以看 出,在 L n x内核五个子系统中 , iu 进程调度子系统 采用 管道 通信 机制 , 父进 程与子进 程之间 , 或者兄弟进程 是整个 内核其它系统顺利工作 的关键部分 , 无论是文件 系统进 这类 近亲进程 之间, 可 以通过系 统调 用建 立一个简单的通信 程 还是网络服务进程 , 都依靠进 程调度来获取 C U资源 才能正 管道 , P 但这类通 信管道只能 由父进程建立 , 管道两端的进程都 常运行。虽然 L nx是多用户 、多任务操作系统 ,但其多个进 iu ( 下转第 15页 ) 1

Linux信号(signal)机制分析

Linux信号(signal)机制分析【摘要】本⽂分析了Linux内核对于信号的实现机制和应⽤层的相关处理。

⾸先介绍了软中断信号的本质及信号的两种不同分类⽅法尤其是不可靠信号的原理。

接着分析了内核对于信号的处理流程包括信号的触发/注册/执⾏及注销等。

最后介绍了应⽤层的相关处理,主要包括信号处理函数的安装、信号的发送、屏蔽阻塞等,最后给了⼏个简单的应⽤实例。

【关键字】软中断信号,signal,sigaction,kill,sigqueue,settimer,sigmask,sigprocmask,sigset_t1 信号本质软中断信号(signal,⼜简称为信号)⽤来通知进程发⽣了异步事件。

在软件层次上是对中断机制的⼀种模拟,在原理上,⼀个进程收到⼀个信号与处理器收到⼀个中断请求可以说是⼀样的。

信号是进程间通信机制中唯⼀的异步通信机制,⼀个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。

进程之间可以互相通过系统调⽤kill发送软中断信号。

内核也可以因为内部事件⽽给进程发送信号,通知进程发⽣了某个事件。

信号机制除了基本通知功能外,还可以传递附加信息。

收到信号的进程对各种信号有不同的处理⽅法。

处理⽅法可以分为三类:第⼀种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。

第⼆种⽅法是,忽略某个信号,对该信号不做任何处理,就象未发⽣过⼀样。

第三种⽅法是,对该信号的处理保留系统的默认值,这种缺省操作,对⼤部分的信号的缺省操作是使得进程终⽌。

进程通过系统调⽤signal 来指定进程对某个信号的处理⾏为。

2 信号的种类可以从两个不同的分类⾓度对信号进⾏分类:可靠性⽅⾯:可靠信号与不可靠信号;与时间的关系上:实时信号与⾮实时信号。

2.1 可靠信号与不可靠信号Linux信号机制基本上是从Unix系统中继承过来的。

早期Unix系统中的信号机制⽐较简单和原始,信号值⼩于SIGRTMIN的信号都是不可靠信号。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档