linux进程间通信PPT课件

合集下载

linux程序设计课件 第7章-进程间的通信

linux程序设计课件 第7章-进程间的通信
第7章 进程间的通信
本章重点
1. 进程通信中信号的概念及信号处理。 2. 进程间的管道通信编程。 3. 进程间的内存共享编程。 4. 进程间队列通信编程。
2
进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区, P1进程把数据从用户空间拷到内核缓冲区,P2进程再从内核缓冲区把 数据读走,如图7.1所示。内核提供的这种机制称为进程间通信(IPC, InterProcess Communication)。
例7.2 下列程序应用函数alarm(10)在运行10秒后发送信号 SIGALARM,程序接收到SIGALARM信号就被终止。
7-2源程序
[root@localhost root]# ./7-2
正在计数中:0 正在计数中:1 ........ 正在计数中:905 闹钟
11
7.2 信 号
例7.3 设计一个程序,要求用户进程创建一个子进程,父进程向子进 程发出SIGKILL信号,子进程收到此信号,结束子进程的运行。
24
7.3.1 无名管道操作
管道允许在进程之间按先进先出的方式传送数据, 是进程间通信的一种常见的方式。 例如: [root@localhost root]# ls | more
无名管道操作时,建立管道用pipe函数。管道操作分以下步骤: 1. 父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端; 2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向 同一管道; 3. 父进程关闭管道读取端,子进程关闭管道写入端。父进程可以往管 道里写,子进程可以从管道里读,管道是用环形队列实现的,数据从 写入端流入从读取端流出,这样就实现了进程间通信。
在Linux中,管道是一种特殊的文件,对一个进程来说,管道 的写入和读取与一个普通文件没有区别。

LINUX内核进程管理PPT幻灯片

LINUX内核进程管理PPT幻灯片

❖ suid和sgid是根据POSIX标准引入的,在系统调用改变uid 和gid时,用于保留真正的uid和gid。
❖ fsuid和fsgid称为文件系统的uid和gid,用于对文件系统操
作时的合法性检查,是LINUX独特的标识类型。它们一般分
别和euid和egid一致,但在NFS文件系统中NFS服务器需要
SIGSTP、SIGTTIN 或SIGTTOU)的反应; 其二是受到父进程ptrace调用的控制,
而暂时将处理机交给控制进程。
35
◆ ZOMBIE: 僵尸状态。 表示进程结束但尚未消亡的一种状态。 此时进程已经结束运行并释放大部分资
源,但尚未释放进程控制块。
36
进程调度
调度程序(scheduler)用来实现进程状态 之间的转换。
0 1 //等待资源 2 4 //等待信号 8
29
◆ RUNNING: 正在运行,或者在就绪队列中等待运行
的进程。 也就是上面提到的运行态和就绪态进程
的综合。 一个进程处于RUNNING状态,并不代表
它一定在被执行。
31
由于在多任务系统中,各个就绪进程需 要并发执行,所以在某个特定时刻,这些处 于RUNNING状态的进程之中,只有一个能 够得到处理机,而其他进程必须在一个就绪 队列中等待。
4
2. 动态性
进程与程序的区别在于,程序只是一个静态的 指令集合,而进程是一个正在系统中活动的指令集 合。
在进程中加入了时间的概念。进程具有自己的 生命周期和各种不同的状态,这些概念在程序中都 是不具备的。
5
由于以上两个性质,又可以衍生出进程 的第三个重要特性,即并发性。
若干个进程可以在单处理机状态上并发 执行。注意并发性(concurrency)和多处理机 并行(parallel)是两个不同的概念。

LINUX内核进程管理PPT幻灯片

LINUX内核进程管理PPT幻灯片
信号发生时,内核中断当前的进程,进 程执行处理函数来响应信号,结束后恢复正 常的进程处理。
信号有自己的名称和特定的编号,见表 3-1所示。
Hale Waihona Puke 19进程状态进程是一个动态的实体,故而它是有生 命的。
从创建到消亡,是一个进程的整个生命 周期。
在这个周期中,进程可能会经历各种不 同的状态。
一般来说,所有进程都要经历以下3种状 态。
❖ suid和sgid是根据POSIX标准引入的,在系统调用改变uid 和gid时,用于保留真正的uid和gid。
❖ fsuid和fsgid称为文件系统的uid和gid,用于对文件系统操
作时的合法性检查,是LINUX独特的标识类型。它们一般分
别和euid和egid一致,但在NFS文件系统中NFS服务器需要
16
3 进程的状态和调度
17
Linux系统信号
信号主要用于通知进程异步事件的发生。 在Linux中可以识别29种不同的信号,这些信号 中的大部分都有了预先定义好的意义,
进程可以显式的用kill或killpg系统调用来 向另一个进程发信号。
18
进程可以通过提供信号处理函数来取代 对于任意信号的缺省反应,这种缺省反应一 般都是终止进程。
uid=euid=fsuid, gid=egid=fsgid。
10
进程标识:
❖ uid和gid是运行进程的用户标识和用户组标识。
❖ euid和egid又称为有效的uid和gid。出于系统安全权限的考 虑,运行程序时要检查euid和egid的合法性。通常,uid等 于euid,gid等于egid。有时候,系统会赋予一般用户暂时 拥有root的uid和gid(作为用户进程的euid和egid),以便 于进行运作。

LINUX系统进程的消息通信完整ppt

LINUX系统进程的消息通信完整ppt
实验5 LINUX系统进程的消息通信
实验5 Linux系统进程的消息通信
一.本实验目:
熟悉支持消息通信机制及消息量机制。 熟悉支持消息通信机制。
1
实验5 LINUX系统进程的消息通信
二.实验预备内容:
2
实验5 LINUX系统进程的消息通信
三.实验内容:
消息的创建,发送和接收。 1、使用系统调用 msgget( ),msgsnd( ),msgrev( ) 及 msgctl( )编制一 长度为1K的消息的发送和接收程序。 观察上面程序,说明控制消息队列系统调用 msgctl( )在此起什么作用?
(2)SERVER端建立一个Key为75的消息队列,等待 观察上面程序,说明控制消息队列系统调用msgctl( )在此起什么作用?
CLIENT每发送一条消息后显示一句“(client)sent”。 消息的创建,发送和接收。
其他进程发来的消息。当遇到类型为1的消息,则作为 1、使用系统调用msgget( ),msgsnd( ),msgrev( ) 及 msgctl( )编制一长度为1K的消息的发送和接收程序。
实验5 LINUX系统进程的消息通信 熟悉支持消息通信机制。
(3)CLIENT端使用key为75的消息队列,先后发送 实验5 Linux系统进程的消息通信
(1)为了便于操作和观察结果,用一个程序作为“引子”,先后fork( )两个子进程,SERVERT CLIENT,进行通信。
实熟验悉类5支持LIN消型U息X通系为信统机进1制程。的0消到息通1信 的消息,然后退出。最后的一个消息,即 是SERVER端需要的结束信号。CLIENT每发送一条消 息后显示一句“(client)sent”。 (4)父进程在SERVER和CLIENT均退出后结束。

Linux的进程和进程间通信 操作系统课件

Linux的进程和进程间通信 操作系统课件
◦ #include <sys/types.h> ◦ #include <sys/ipc.h> ◦ #include <sys/shm.h> ◦ int shmget(key_t key,int size,int shmflg); ◦ void *shmat(int shmid,const void *shmaddr,int shmflg); ◦ int shmdt(const void *shmaddr); ◦ int shmctl(int shmid,int cmd,struct shmid_ds *buf);
例子1(续)
} else if(child==0) { int i; printf("I am the child:%ld\n",getpid()); for(i=0;i<1000000;i++) i++; i=5; printf("I exit with %d\n",i); exit(i); } while(((child=wait(&status))==-1)&(errno==EINTR)); }
区分父进程和子进程:
◦ 跟踪fork返回值
失败:-1 否则
父进程fork 返回子进程的ID fork 子进程返回0
可根据这个返回值来区分父子进程
调用系统程序
调用系统程序, 可以使用系统调用exec 族调用。 exec 族调用有着5 个函数:
#include <unistd.h> int execl(const char *path,const char *arg,...); int execlp(const char *file,const char *arg,...); int execle(const char *path,const char *arg,...); int execv(const char *path,char *const argv[]); int execvp(const char *file,char *const argv[]):

linux 进程间通信ppt

linux 进程间通信ppt

内核 管道


父子进程之间的管道通信(2)

父子进程分别拥有自己的读写通道,为了实现父子进程之 间的读写,只需把无关的读端或写端的文件描述符关闭即 可。此时,父子进程之间就建立起了一条“子进程写入父 进程读取”的通道。
父进程 fd[0] fd[1] 子进程 fd[0] fd[1]
最初UNIX的进程间通信 System V 进程间通信 Socket进程间通信 POSIX进程间通信

Linux 进程间 通信

进程间通信方式的种类(1)
(1)管道(Pipe)及有名管道(named pipe):管道可用于具 有亲缘关系进程间的通信,有名管道,除具有管道所具有的 功能外,它还允许无亲缘关系进程间的通信。 (2)信号(Signal):信号是在软件层次上对中断机制的一种 模拟,它是比较复杂的通信方式,用于通知进程有某事件发 生,一个进程收到一个信号与处理器收到一个中断请求效果 上可以说是一样的。 (3)消息队列(Messge Queue):消息队列是消息的链接表, 包括Posix消息队列SystemV消息队列。它克服了前两种通信 方式中信息量有限的缺点,具有写权限的进程可以按照一定 的规则向消息队列中添加新消息;对消息队列有读权限的进 程则可以从消息队列中读取消息。
13

示例

阅读并运行示例8-2-2。

标准流管道 (1)


与Linux的文件操作中有基于文件流的标准I/O操作一样,管道 的操作也支持基于文件流的模式。这种基于文件流的管道主 要是用来创建一个连接到另一个进程的管道,这里的“另一 个进程”也就是一个可以进行一定操作的可执行文件,例如, 用户执行“ls -l”或者自己编写的程序“./pipe”等。由于这一类 操作很常用,因此标准流管道就将一系列的创建过程合并到 一个函数popen()中完成。它所完成的工作有以下几步。

第九讲Linux进程及通信

第九讲Linux进程及通信
• SCHED_OTHER 非实时进程,基于优先级的轮转 法 • SCHED_FIFO 实时进程,用先进先出算法 • SCHED_RR 实时进程,用基于优先权的轮转 法
priority
• 进程优先级(静态),给出进程每次获取cpu 后可使用的时间(按jitty计算)。通过系统 调用sys_setpriority()改变。 • Linux 的基准时间(kernel/timer.c)。系统 初始化时清零,以后每隔10ms由时钟中断服务 程序,do_timer增1。
schedule() 函数(kenel\sched.c)
• 如果给每个进程分配一个基本的时间片?
/* Do we need to re-calculate counters? */ if (unlikely(!c)) { struct task_struct *p; spin_unlock_irq(&runqueue_lock); read_lock(&tasklist_lock); for_each_task(p) p->counter = (p->counter >> 1) + NICE_TO_TICKS(p>nice); read_unlock(&tasklist_lock); spin_lock_irq(&runqueue_lock); goto repeat_schedule; }
• 新的counter等于旧的counter的一半加增量(取决 于nice的值)
schedule() 函数
• 在当前进程时间片到期,或者因为I/O阻塞 等情况下,schedule函数被调用。 • schedule函数选择优先级最高的进程运行
next = idle_task(this_cpu); c = -1000; list_for_each(tmp, &runqueue_head) { p = list_entry(tmp, struct task_struct, run_list); if (can_schedule(p, this_cpu)) { int weight = goodness(p, this_cpu, prev->active_mm); if (weight > c) c = weight, next = p; } }

实验六进程间通信28页PPT

实验六进程间通信28页PPT

1.3 管道和消息队列—无名管道
int pipe(int fd[2]);一般的文件I/O函数都可用
❖ 读数据规则
若管道的写端不存在,读出字节数为0 写端存在时,若请求字节数大于PIPE_BUF,则返回管道中的现有数
据;否则返回请求的字节数
❖ 写入规则
不保证写入的原子性,若有空闲区域,写进程就会试图写入管道, 若读进程不读走数据,则写操作将一直阻塞
如果没有进程写打开,则设置了阻塞标志的读操作阻塞
1.3 管道和消息队列—命名管道(3)
❖ 对于设置了阻塞标志的写操作:
当要写入的数据量不大于PIPE_BUF时,若管道空闲缓冲区不足以容 纳要写入的字节数,则睡眠,直到缓冲区满足要求时,一次性写操 作(原子性)
息量少、管道只能承载无格式字节流以及缓冲区大 小受限等缺点 ❖ 可以用流管道或套接口方式取代
1.1 Linux进程间通信—共享内存
❖ 在系统内核分配一块缓冲区,多个进程都可以访问 该缓冲区
❖ 效率高:进程可以直接读写内存,不需任何数据拷 贝,避免了内核空间与用户空间的切换
❖ 同步和协议都不受程序员控制,必须确保将句柄传 递给子进程和线程,需与其它通信机制结合使用, 来达到进程间的同步及互斥
1.1 Linux进程间通信—套接口
❖ 也称套接字,用于不同机器之间的进程间通信 ❖ 通信域是用来说明套接口通信的协议,创建套接口
时要指明它的通信域 ❖ 常见的有:UNIX域套接口、网际通信域 ❖ 系统的网络编程接口,以文件的形式实现(属于
sockfs特殊文件系统)
1.2 进程软中断通信
❖ 即信号,提供一种简单的处理异步事件的方法 ❖ 信号机制是对中断机制的一种模拟,又称为软中断 ❖ 信号与中断的相似点
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2
.
linux进程间通信(IPC)由以下几部分发展而来:
早期UNIX进程间通信、基于System V进程间通信、 基于Socket进程间通信和POSIX进程间通信。
UNIX进程间通信方式包括:管道、FIFO、信号。
System V进程间通信方式包括:System V消息队 列、System V信号灯、System V共享内存。
普通的Linux shell都允许重定向,而重定向使用的就是 管道。例如:
ps | grep vsftpd
管道是单向的、先进先出的、无结构的、固定大小的字 节流,它把一个进程的标准输出和另一个进程的标准输入 连接在一起。写进程在管道的尾端写入数据,读进程在管 道的首端读出数据。数据读出后将从管道中移走,其它读 进程都不能再读到这些数据。管道提供了简单的流控制机 制。进程试图读空管道时,在有数据写入管道前,进程将 一直阻塞。同样,管道已经满时,进程再试图写管道,在 其它进程从管道中移走数据之前,写进程将一直阻塞。
if((fp=popen(cmd,"r"))==NULL)
perror("popen");
while((fgets(buf,BUFSIZE,fp))!=NULL)
POSIX进程间通信包括:posix消息队列、posix信 号灯、posix共享内存。
3
.
现在linux使用的进程间通信方式: (1)管道(pipe)和有名管道(FIFO) (2)信号(signal) (3)消息队列 (4)共享内存 (5)信号量 (6)套接字(socket)
4
.
2、管道通信
必须在系统调用fork( )中调用pipe( ),否则子进 程将不会继承文件描述符。
当使用半双工管道时,任何关联的进程都必须 共享一个相关的祖先进程。因为管道存在于系统 内核之中,所以任何不在创建管道的进程的祖先 进程之中的进程都将无法寻址它。而在命名管道 中却不是这样。
11
.
2.4 标准流管道
管道主要用于不同进程间通信。
5
.
2.1 管道创建与关闭
创建一个简单的管道,可以使用系统调用pipe( )。它接 受一个参数,也就是一个包括两个整数的数组。如果系统 调用成功,此数组将包括管道使用的两个文件描述符。创 建一个管道之后,一般情况下进程将产生一个新的进程。
系统调用:pipe( );
原型:int pipe(int fd[2]);
通知它(它们)发生了某种事件(如进程终止时要通知父 进程)。 资源共享:多个进程之间共享同样的资源。为了作到这一 点,需要内核提供锁和同步机制。 进程控制:有些进程希望完全控制另一个进程的执行(如 Debug进程),此时控制进程希望能够拦截另一个进程的 所有陷入和异常,并能够及时知道它的状态改变。
int main()
{
int pipe_fd[2];if(pipe(pipe_fd)<0){
printf("pipe create error\n");
return -1;
}
else
printf("pipe create success\n");
close(pipe_fd[0]);
close(pipe_fd[1]);
12
.
使用popen()创建的管道必须使用pclose( )关闭。其实, popen/pclose和标准文件输入/输出流中的fopen()/fclose() 十分相似。
库函数:pclose();
原型:int pclose( FILE *stream );
返回值:返回调用状态。
13
.
#include <stdio.h>
与linux中文件操作有文件流的标准I/O一样,管道的操作 也支持基于文件流的模式。接口函数如下
库函数:popen();
原型: FILE *popen ( char *command, char *type);
返回值:如果成功,返回一个新的文件流。如果无法 创建进程或者管道,返回NULL。
管道中数据流的方向是由第二个参数type控制的。此参 数可以是r或者w,分别代表读或写。但不能同时为读和写。 在Linux系统下,管道将会以参数type中第一个字符代表的 方式打开。所以,如果你在参数type中写入rw,管道将会 以读的方式打开。
}
8
.
2.2 管道读写
管道主要用于不同进程间通信。实际上,通常先创建一 个管道,再通过fork函数创建一个子进程。
图2 父子进程管道的文件描述符对应关系
9
.
子进程写入和父进程读的命名管道:
图 3 关闭父进程fd[1] 和 子进程[0]
10
.
2.3 管道读写注意事项
可以通过打开两个管道来创建一个双向的管道。 但需要在子进程中正确地设置文件描述符。
返回值:如果系统调用成功,返回0。如果系统调用失 败返回- 1:
errno = EMFILE (没有空闲的文件描述符)
EMFILE (系统文件表已满)
EFAULT (fd数组无效)
6
.
注意:fd[0] 用于读取管道,fd[1] 用于写入管 道。
图1 linux中管道与文件描述符的关系
7
.
#include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h>
linux进程间通信
1. 进程间通信概述 2. 管道通信 3. 信号 4. 共享内存 5. 消息队列
1
.
1、进程间通信概述
进程间通信有如下一些目的: 数据传输:一个进程需要将它的数据发送给另一个进程,
发送的数据量在一个字节到几兆字节之间。 共享数据:多个进程想要操作共享数据,一个进程对共享
数据的修改,别的进程应该立刻看到。 通知事件:一个进程需要向另一个或一组进程发送消息,
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#define BUFSIZE 1024
int main()
{
FILE *fp;
char *cmd = "ps -ef";
char buf[BUFSIZE];
buf[BUFSIZE] = '\0';
相关文档
最新文档