实验二 Linux进程间通信

合集下载

Linux进程间通信

Linux进程间通信

1. IPC(Interprocess Communication)简介 (1)2. 信号通信signal (2)3. 标准流管道 (3)4. 无名管道(PIPE) (4)5. 命名管道(FIFO) (6)5.1.创建、删除FIFO文件 (6)5.2.打开、关闭FIFO文件 (7)5.3.读写FIFO (7)6. 共享内存 (8)7. 消息队列 (16)8. 信号量 (19)1.IPC(Interprocess Communication)简介Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的。

而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间的通信方面的侧重点有所不同。

前者是对UNIX早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,其通信进程主要局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。

而Linux则把两者的优势都继承了下来UNIX进程间通信(IPC)方式包括管道、FIFO以及信号。

System V进程间通信(IPC)包括System V消息队列、System V信号量以及System V共享内存区。

Posix 进程间通信(IPC)包括Posix消息队列、Posix信号量以及Posix共享内存区。

linux进程之间的通讯主要有下面几种:1 管道pipe和命名管道:管道有亲缘关系进程间的通信,命名管道还允许无亲缘关系进程间通信2 信号signal:在软件层模拟中断机制,通知进程某事发生3 消息队列:消息的链表包括posix消息队列和SystemV消息队列4 共享内存:多个进程访问一块内存主要以同步5 信号量:进程间同步6 套接字socket:不同机器间进程通信下面是对它们的详解:·管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

linux系统进程间通信的方式

linux系统进程间通信的方式

linux系统进程间通信的方式
Linux系统进程间通信的方式有多种,其中比较常见的有管道、消息队列、信号量、共享内存和套接字等。

1. 管道:管道是一种半双工的通信方式,其本质是一块内存缓冲区。

它分为匿名管道和命名管道,匿名管道只能用于父子进程之间的通信,而命名管道则可以用于任意两个进程之间的通信。

2. 消息队列:消息队列是一种通过内核实现的进程间通信机制,其可以实现多对多的进程通信。

消息队列可以设置消息的优先级和大小,发送方通过消息队列发送消息,接收方则通过读取消息队列的方式获取消息。

3. 信号量:信号量是一种用于同步多进程共享资源的机制。

它可以用来解决多个进程同时访问共享资源时所产生的竞争问题。

通过信号量机制,进程可以申请资源、释放资源以及等待资源。

4. 共享内存:共享内存是一种高效的进程间通信方式,它允许多个进程共享同一块物理内存空间。

多个进程可以直接访问这块内存,从而实现进程间数据的快速传递。

5. 套接字:套接字是一种跨网络的进程间通信方式,它可以实现不同主机上的进程之间的通信。

套接字可以用于实现客户端和服务器的通信,也可以用于实现进程之间的通信。

总的来说,不同的进程间通信方式有不同的应用场景,开发者需要根据实际的需求选择合适的进程间通信方式。

- 1 -。

Linux进程间通信

Linux进程间通信

Linux进程间通信一、进程间通信概述进程通信有如下一些目的:A、数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间B、共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。

C、通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。

D、资源共享:多个进程之间共享同样的资源。

为了作到这一点,需要内核提供锁和同步机制。

E、进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

Linux 进程间通信(IPC)以下以几部分发展而来:早期UNIX进程间通信、基于System V进程间通信、基于Socket进程间通信和POSIX进程间通信。

UNIX进程间通信方式包括:管道、FIFO、信号。

System V进程间通信方式包括:System V消息队列、System V信号灯、System V共享内存、POSIX进程间通信包括:posix消息队列、posix信号灯、posix共享内存。

现在linux使用的进程间通信方式:(1)管道(pipe)和有名管道(FIFO)(2)信号(signal)(3)消息队列(4)共享内存(5)信号量(6)套接字(socket)二、管道通信普通的Linux shell都允许重定向,而重定向使用的就是管道。

例如:ps | grep vsftpd .管道是单向的、先进先出的、无结构的、固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。

写进程在管道的尾端写入数据,读进程在管道的道端读出数据。

数据读出后将从管道中移走,其它读进程都不能再读到这些数据。

管道提供了简单的流控制机制。

进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。

同样,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。

04--Linux系统编程-进程间通信

04--Linux系统编程-进程间通信

IPC方法Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。

任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。

在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。

随着计算机的蓬勃发展,一些方法由于自身设计缺陷被淘汰或者弃用。

现今常用的进程间通信方式有:①管道(使用最简单)②信号(开销最小)③共享映射区(无血缘关系)④本地套接字(最稳定)管道管道的概念:管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。

调用pipe系统函数即可创建一个管道。

有如下特质:1. 其本质是一个伪文件(实为内核缓冲区)2.由两个文件描述符引用,一个表示读端,一个表示写端。

3. 规定数据从管道的写端流入管道,从读端流出。

管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。

管道的局限性:①数据自己读不能自己写。

②数据一旦被读走,便不在管道中存在,不可反复读取。

③由于管道采用半双工通信方式。

因此,数据只能在一个方向上流动。

④只能在有公共祖先的进程间使用管道。

常见的通信方式有,单工通信、半双工通信、全双工通信。

pipe函数创建管道int pipe(int pipefd[2]); 成功:0;失败:-1,设置errno函数调用成功返回r/w两个文件描述符。

无需open,但需手动close。

规定:fd[0] →r;fd[1] →w,就像0对应标准输入,1对应标准输出一样。

向管道文件读写数据其实是在读写内核缓冲区。

管道创建成功以后,创建该管道的进程(父进程)同时掌握着管道的读端和写端。

Linux进程间通信

Linux进程间通信

如何指定信号处理方式?
表 7-16 所需头文件 函数原型 #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) signum:信号代码,可以为除 SIGKILL 及 SIGSTOP 外的任何一个特定有效的信号 Act:指向 struct sigaction struct sigaction { void (*sa_handler)(int signo); sigset_t sa_mask; int sa_flags; void (*sa_restore)(void); } Oldact:指向 struct sigaction 函数返回值 0 表示成功, -1 表示有错误发生 siga ct ion ( ) 函数语法要点
void main() { printf("Waiting for signal SIGINT or SIGQUIT...\n"); signal(SIGINT, my_func); //收到信号SIGINT,转去执行函数my_func for(;;); exit(0); }
例2:子进程等收到信号才结束
if (pid == 0) {/*子进程*/ printf("Child(pid : %d) is waiting for any signal\n", getpid()); raise(SIGSTOP);// 使子进程暂停 exit(0); }
else {/*父进程*/ if ((waitpid(pid, NULL, WNOHANG)) == 0) { if ((ret = kill(pid, SIGKILL)) == 0) //向子进程发结束信号 printf("Parent kill %d\n",pid); } waitpid(pid, NULL, 0); exit(0); }

linux进程通信方法

linux进程通信方法

linux进程通信方法Linux进程通信方法在Linux操作系统中,进程之间的通信是非常重要的。

进程通信(Inter-Process Communication,简称IPC)是指在多个进程之间进行数据交换和共享的机制。

Linux提供了多种进程通信方法,包括管道、命名管道、信号量、共享内存、消息队列和套接字等。

下面将详细介绍每种通信方法的使用。

1. 管道(Pipe)管道是最基本的进程通信方法之一,它可以在父进程和子进程之间创建一个单向通道,数据只能单向流动。

管道可以通过命令行工具`pipe`创建,也可以通过C语言函数`pipe()`创建。

在管道中,数据的流动是按照先进先出的原则进行的。

父进程和子进程通过管道进行通信时,必须遵循一定的协议,以确保数据的正确传输。

2. 命名管道(Named Pipe)命名管道也是一种进程间通信的方法,它与管道类似,但不同的是命名管道可以通过文件系统中的路径进行访问。

命名管道可以通过命令行工具`mkfifo`创建,也可以通过C语言函数`mkfifo()`创建。

命名管道是一种有名的管道,可以在多个进程之间进行通信,而不仅仅是父进程和子进程。

3. 信号量(Semaphore)信号量是一种用于实现进程间互斥和同步的方法。

通过信号量,进程可以申请和释放资源,以保证进程之间的顺序执行。

Linux提供了一组信号量函数,包括`semget()`、`semop()`和`semctl()`等。

通过这些函数,进程可以创建信号量、进行P操作和V操作,以及控制信号量的属性。

4. 共享内存(Shared Memory)共享内存是进程间通信的一种高效的方法,它可以使多个进程共享同一块内存空间。

通过共享内存,进程可以直接读写内存中的数据,而不需要进行复制操作。

Linux提供了一组共享内存函数,包括`shmget()`、`shmat()`和`shmdt()`等。

通过这些函数,进程可以创建共享内存段、将共享内存映射到自己的地址空间,并且可以解除共享内存的映射关系。

linux进程通信

一、linux下进程间通信概述AT&T的贝尔实验室,对UNIX早期的进程间通信进行了改进和扩充,形成了“system V IPC”,其通信进程主要局限在单个计算机内。

BSD(加州大学伯克利分校伯克利软件发布中心),跳过了该限制,形成了基于套接字(socket)的进程间通信机制。

linux继承了上述所有通信方式:1、传统通信方式无名管道(pipe),有名管道(fifo),信号(signal)2、system V IPC对象共享内存(share memory),消息队列(message queue),信号灯(又叫信号灯集,与线程中的信号灯要区分清楚,semaphore)3、BSD套接字(socket,这个其实主要用于网络间线程通信,所以肯定可以支持本机线程通信)二、每种通信方式的介绍1、无名管道(pipe)无名管道只能用于具有亲缘关系的进程间通信,即父子进程,兄弟进程等。

无名管道由内核来维护,是一种半双工的通信模式,具有固定的读端和写端(读端只能读,写端只能写),可以将其看成文件,使用write和read函数进行读写。

由于子进程完全继承父进程打开的文件描述符,所以父子进程可以通过pipe进行通信创建无名管道pipe需要用到函数:int pipe(int fd[2]);fd[0]固定为读端,fd[1]固定为写端。

举例如下:int fd[2];pipe(fd);这样,一个进程通过fd[1]写入数据,另一个就可以从fd[0]读出来了。

注意无名管道无读者时,写操做将会返回一个信号,如果进程未对此信号进行捕捉,会被信号杀死(即进程退出)。

若无写者,则读操作会返回0无名管道不能保证原子性,既如果有多个进程同时向同一个管道里面写数据,可能会造成数据交错,得不到我们想要的结果,这点希望读者能够在编程时注意。

2、有名管道fifo有名管道可以使互不相关的两个进程之间进行通信,有名管道想普通文件一样在linux文件系统中可见,可以通过路径来指定,用open,write,read等函数进行操作,而且他与无名管道不通,他可以保证写入数据的原子性,而且遵循先进先出的原则。

linux进程间通信课程设计

linux进程间通信课程设计一、课程目标知识目标:1. 理解Linux操作系统中进程间通信的基本概念与原理;2. 掌握进程间通信的几种主要机制,如管道、消息队列、共享内存和信号量;3. 学会使用相关API进行进程间数据传输和控制流程;4. 了解进程间同步和互斥的概念,并掌握相关实现方法。

技能目标:1. 能够编写简单的Linux进程间通信程序;2. 能够分析进程间通信程序的执行流程,并解决通信过程中可能出现的常见问题;3. 能够运用所学知识解决实际场景中的进程间通信问题。

情感态度价值观目标:1. 培养学生对操作系统和底层编程的兴趣,激发学生探究新技术的好奇心;2. 培养学生的团队协作精神,提高学生在团队项目中的沟通与协作能力;3. 培养学生严谨、认真的学习态度,使学生认识到编程过程中细节的重要性。

本课程针对高年级计算机专业学生,结合课程性质、学生特点和教学要求,将课程目标分解为具体的学习成果。

通过本课程的学习,学生将掌握Linux进程间通信的基本知识和技能,培养实际编程能力和团队协作精神,为后续学习操作系统及相关领域知识打下坚实基础。

二、教学内容1. 进程间通信概述- 了解进程与线程的概念及区别;- 掌握Linux操作系统中进程间通信的基本需求及分类。

2. 管道通信- 学习管道的基本原理和使用方法;- 掌握无名管道和命名管道(FIFO)的创建、读写操作及注意事项。

3. 消息队列- 了解消息队列的基本概念和原理;- 掌握消息队列的创建、发送、接收和删除操作。

4. 共享内存- 学习共享内存的基本原理和用途;- 掌握共享内存的创建、映射和解除映射操作,以及同步机制。

5. 信号量- 了解信号量的基本概念和用途;- 掌握信号量的创建、P操作和V操作,以及应用场景。

6. 信号- 学习信号的基本概念、分类和作用;- 掌握信号的发送、捕捉和处理方法。

教学内容根据课程目标进行选择和组织,保证科学性和系统性。

本教学内容涵盖教材中关于Linux进程间通信的相关章节,按照教学进度安排,逐一向学生传授各通信机制的基本原理和实际应用。

Linux下进程间通信--共享内存:最快的进程间通信方式

Linux下进程间通信--共享内存:最快的进程间通信⽅式共享内存:⼀、概念:共享内存可以说是最有⽤的进程间通信⽅式,也是最快的IPC形式。

两个不同进程A、B共享内存的意思是,同⼀块物理内存被映射到进程A、B各⾃的进程地址空间。

进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。

由于多个进程共享同⼀块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

采⽤共享内存通信的⼀个显⽽易见的好处是效率⾼,因为进程可以直接读写内存,⽽不需要任何数据的拷贝。

对于像管道和消息队列等通信⽅式,则需要在内核和⽤户空间进⾏四次的数据拷贝,⽽共享内存则只拷贝两次数据[1]:1.⼀次从输⼊⽂件到共享内存区,2.另⼀次从共享内存区到输出⽂件。

实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建⽴共享内存区域。

⽽是保持共享区域,直到通信完毕为⽌,这样,数据内容⼀直保存在共享内存中,并没有写回⽂件。

共享内存中的内容往往是在解除映射时才写回⽂件的。

因此,采⽤共享内存的通信⽅式效率是⾮常⾼的。

⼆、相关函数:与信号量⼀样,在Linux中也提供了⼀组函数接⼝⽤于使⽤共享内存,⽽且使⽤共享共存的接⼝还与信号量的⾮常相似,⽽且⽐使⽤信号量的接⼝来得简单。

它们声明在头⽂件 sys/shm.h中。

1、shmget函数该函数⽤来创建共享内存,它的原型为:int shmget(key_t key, size_t size, int shmflg);1.第⼀个参数,与信号量的semget函数⼀样,程序需要提供⼀个参数key(⾮0整数),它有效地为共享内存段命名。

shmget函数成功时返回⼀个与key相关的共享内存标识符(⾮负整数),⽤于后续的共享内存函数。

调⽤失败返回-1.不相关的进程可以通过该函数的返回值访问同⼀共享内存,它代表程序可能要使⽤的某个资源,程序对所有共享内存的访问都是间接的,程序先通过调⽤shmget函数并提供⼀个键,再由系统⽣成⼀个相应的共享内存标识符(shmget函数的返回值),只有shmget函数才直接使⽤信号量键,所有其他的信号量函数使⽤由semget函数返回的信号量标识符。

Linux进程间通信示例(多通道)

Linux进程间通信示例(多通道)使用管道进行通信编写程序建立一个无名管道,然后生成3个子进程,使这4个进程利用同一个管道进行通信。

分别试验3写1读、2写2读情况,多次执行,看结果是否一致,并对记录的执行结果进行解释。

【注】没有关于管道的示例程序(因为比较简单),在多端写入时应该使用lockf加锁。

一》3写1读代码如下:#include <unistd.h>#include <signal.h>#include <stdio.h>int pid[3];int main(void){int fd[2];char outpipe[100],inpipe[100];//暂存读出,或要写入的字符串pipe(fd);int i;for(i=0;i<3;i++){pid[i]=fork( );if(pid[i]==0)break;}if(pid[1]==0){lockf(fd[1],1,0);sprintf(outpipe,"child 1 process is sending message!"); write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);}if(pid[2]==0){lockf(fd[1],1,0);sprintf(outpipe,"child 2 process is sending message!"); write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);}if(pid[3]= =0){lockf(fd[1],1,0);sprintf(outpipe,"child 3 process is sending message!"); write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);//释放exit(0);}wait(0);read(fd[0],inpipe,50);printf("%s/n",inpipe);read(fd[0],inpipe,50);printf("%s/n",inpipe);read(fd[0],inpipe,50);printf("%s/n",inpipe);return 0;}运行结果:第一次运行:child 1 process is sending message!child 2 process is sending message!child 3 process is sending message!第十五次:child 1 process is sending message!child 3 process is sending message!child 2 process is sending message!…….(注释:因运行结果受父进程创建子进程的先后顺序影响,一般看到的结果是123,但是理论上,123,321,213等等的运行结果是会出现的,可以通过在分支前加sleep(5),来观察)分析:通过for(i=0;i<3;i++){pid[i]=fork( );if(pid[i]==0)break;可以实现父进程创建3个子进程,同时也避免了子进程再次创建子进程。

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

实验二Linux进程间通信
1.实验目的
(1)分析进程争用临界资源的现象,学习解决进程互斥的方法;
(2)学习如何利用进程的“软中断”、管道机制进行进程间的通信,并加深对上述通信机制的理解;
(3)了解系统调用pipe( )、msgget( )、msgsnd( )、msgrcv( )、msgctl( )、shmget( )、shmat( )、shmdt( )、shmctl( )的功能和实现过程,利用共享存储区机制进
行进程间通信。

2.实验内容
(1)进程的控制
编写一段程序,使用系统调用fork()创建两个子进程。

各进程循环显示不同的信息(如20次):父进程显示:“parent:”加上进程ID,子进程分别显示:“Child1:”(或“Child2:”)加上自己的进程ID。

观察程序执行时屏幕上出现的现象,并分析原因,进一步理解各个进程争夺临界资源(显示器)的情况。

接着在程序中使用系统调用locking( )来给每一个进程加锁,实现进程之间的互斥,试观察并分析出现的现象。

(2)进程的软中断通讯
编制一段程序,实现进程的软中断通讯:使用系统调用fork( )创建两个子进程;再使用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按Del键);在捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发信号;子进程捕捉到信号后分别输出下列信息后终止:
Child process1 is killed by parent!
Child process2 is killed by parent!
父进程等待两个子进程都终止以后,输出如下信息后终止:
Parent process in killed!
(3)进程的管道通讯
编制一段程序,实现进程的管道通讯:使用系统调用pipe( )建立一条管道线;两个子进程分别循环向这条管道写一句话:
Child 1 is sending a message!
Child 2 is sending a message!
而父进程则循环从管道中读出信息,显示在屏幕上。

3.实验提示
(1)用4个基本系统调用实现进程的创建,执行和自我终止:
①fork() 创建一个子进程。

用它创建的子进程是fork调用者进程(即父进程)的复制品,即进程映象。

除了进程标识数以及与进程特性有关的一些参数外,其它与父进程相同,与父进程共享文本段和打开的文件,并都受进程调度程序的调度。

如果创建进程失败,则fork()返回值为-1;若创建进程成功,则从父进程返回值是子进程号,从子进程返回的值是0。

m=fork()。

② wait() 父进程处于阻塞(或等待)状态,等待子进程执行完成终止后继续工作。

其返回值为等待子进程的子进程号。

n=wait()。

③ exit() 子进程自我终止,释放所占资源,通知父进程可以删除自己。

此时它的状态变成P_state=SZOMB。

④ getpid() 获得进程的标识数(进程号),一般是正整数。

P=getpid()。

编程示例:
例1:编写一个程序,父进程生成一个子进程,父进程等待子进程wait(),子进程执行完成后自我终止exit(),并唤醒父进程。

父、子进程执行时打印有关信息。

main()
{ int i,j,k;
if (i=fork()) // 非零值
{ j=wait();
printf("Parent process!\n");
printf(“i=%d j=%d\n”, i, j);
}
else{ k=getpid();
printf("Child process!\n");
printf(“i=%d k=%d\n”, i, k);
}
}
(2)进程的“软中断”通信
它可用于同一用户的进程之间通信。

其方式是:一个进程通过系统调用kill(pid,sig) 向同一用户的其它进程pid发送一个软中断信号;另一进程通过系统调用signal(sig,func)捕捉到信号sig后,执行预先约定的动作func,从而实现这两个进程间的通信。

①发送信号kill(pid,sig),本进程将指定信号sig发送给指定进程pid,其
中参数为pid进程号,pid与sig均为整数值.
②接收信号signal(sig,func),本进程接收到其它进程发送给它的信号后,完成指定的功能func. func一般是函数.
例2. 编写一个程序,父进程生成子进程,父进程发送信号并等待,子进程接收信号并完成某种功能,然后自我终止并唤醒父进程.
int func();
main()
{ int i,j:
signal(17,func);
if(i=fork())
{ printf("Parent: Signal 17 will be send to Child! \n");
kill(i,17);
wait(0);
printf("Parent: finished! \n");
}
else{ sleep(10);
printf("Child: A signal from my Parent is received! \n") ;
exit();
}
}
func()
{printf("It is signal 17 processing function! \n");
执行结果如下:
Parent: Signal 17 will be send to Child!
It is signal 17 processing function!
Child: A signal from my Parent is received!
Parent: finished!
在程序中系统调用sleep(second)用于进程的同步与互斥,自变量是暂停秒数.其功能是使现行进程暂停执行由自变量规定的秒数.
类似的系统调用有pause(),它的功能是暂停执行本进程,等待kill发来的信号,收到信号后再继续执行.
在特殊情况下,常用到如下语句signal(SIGINT,SIG_IGN).它表示遇到了中断信号SIGINT(按Del键).本进程不做任何动作,即勿略该中断信号对本进程的影响.
(3)进程的控制
利用系统调用lockf(fd,mode,size),对指定文件的指定区域(由size指示)进行加锁或解锁,以实现进程的同步与互斥.其中fd是文件描述字;mode是锁定方式,=1表示加锁,=0表示解锁,size是指定文件fd的指定区域,用0表示从当前位置到文件尾.
常用程序段
fd = open( "a.out",2 );
if( i==0 )
{ lockf(fd,1,0);
………
lockf(fd,0,0);
}
例3. 编写一个程序,创建一个文件,文件名为lock.dat,同时父进程创建2个子进程,通过系统调用lockf(),分别让2个子进程对文件加锁,再输出有关信息,然后解锁.
char buf[]={"check lock!\n"};
main()
{ int i,p1,p2,fd;
fd=creat("lock.dat",0644);
write(fd,buf,20);
while((p1=fork())==-1);
if(p1==0)
{lockf(fd,1,0);
for (i=1;i<=3;i++)
printf("child1!\n");
lockf(fd,0,0);
}
else{while((p2=fork())==-1);
if (p2==0)
{lockf(fd,1,0);
for (i=1;i<=4;i++)
printf("child2!\n");
lockf(fd,0,0);
}
else printf("parrent!\n");
}
close(fd);
}
(4)进程管道的通信
建立进程间的管道,格式为:
pipe(fd);
int fd[2];
其中,fd[1] 是写端,向管道中写入;
fd[0] 是读端,从管道中读出;
本质上将其当作文件处理.进程间可通过管道,用write与read来传递数据,但write与read不可以同时进行,在管道中只能有4096字节的数据被缓冲.
例4. 编写一个程序,建立一个pipe,同时父进程产生一个子进程,子进程向pipe中写入一个字符串,父进程从中读出该字符串,并每隔3秒种输出打印一次.
{ int x,fd[2];
char S[30];
pipe(fd);
for (;;)
{ x=fork();
if (x==0)
{sprintf(S,"Good-night!\n"); write(fd[1],S,20);
sleep(3);
exit(0);
}
else{wait(0);
read(fd[0],S,20);
printf("**********\n",S); }
}
}。

相关文档
最新文档