第五周--------->线程

目录

2、进程间通信方式

3、传统的unix通信方式

3.1 无名管道

3.2 有名管道

3.3 信号

4、systemV进程间通信方式

4.1 systemV IPC基础

4.2 key值和ID值

4.3 消息队列

4.4共享内存

5、信号量不能传递数据,一般和共享内存配合使用,实现共享内存同步

5.进程间通信方式比较


2、进程间通信方式

UNIX平台进程通信方式

       早期进程间通信方式

       AT&T的贝尔实验室,对Unix早期的进程间通信进行了改进和扩充,形成了“systemV IPC“,其通信进程主要局限在单个计算机内。

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

Linux继承了上述所有的通信方式

3、传统的unix通信方式

3.1 无名管道

3.1.1 无名管道的特点:

1.只能用于具有亲缘关系(父子进程/兄弟进程)的进程之间的通信,速度慢,容量有限

2.半双工的通信方式,具有固定的读端fd[0]和写端fd[1]

3.管道可以看成一种特殊的文件,对于它的读写我们实用文件IO中read和write

3.1.2 创建管道

#include<unistd.h>

int pipe(int fd[2])

参数 fd:包含两个元素的整型数组

返回值 成功:0   出错:-1

       管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1]。其中fd[0]固定用于读管道,而fd[1]固定用于写管道。

       构成了一个半双工的通道。

3.1.3 测试管道大小

3.1.4 父子进程间的通信

 

3.1.5 无名管道需要注意的问题

3.2 有名管道

3.2.1 有名管道的特点

1.有名管道时对无名管道的改进,它可以使互不相关的两个进程互相通信,并且再文件系统中可见,可以通过文件名来找到。

2.半双工的通信方式,进程通过文件IO来操作有名管道。

3.有名管道遵循先进先出原则,不支持lseek()

3.2.2 创建管道

#include<unistd.h>

#include<fcntl.h>

#include<sys/types.h>

int mkfifo(const char *filename,mode_t mode);

参数 filename:要创建的管道

        mode:指定创建的管道的访问权限,一般用8进制数表示

返回值 成功:0   出错:-1

3.3 信号

3.3.1 信号的特点:

       信号是以一种异步通信方式

3.3.2 信号产生的方式

3.3.2.1 硬件产生信号

ctrl+z     SIGTSTP

       该信号用于交互停止进程,用户在输入SUSP字符时发出这个信号

ctrl+c     SIGINT

       该信号在用户输入INTR字符时发出,终端驱动程序发送此信号并送到前台进程中的每一个进程

ctrl+\     SIGQUIT

       该信号和SIGINT类似,但由QUIT字符来控制

3.3.2.2 内核发送信号

alarm()

alarm()也称为闹钟函数,它可以在进程中设置一个定时器。当定时器指定的时间到了时,它就向进程发送SIGALRM信号。要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm()之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。

#include<unistd.h>

unsigned int alarm(unsigned int seconds);

seconds:指定秒数,系统经过seconds秒之后向该进程发送SIGALRM信号

返回值:

       成功 如果调用此alarm()前,进程中已经设置了闹钟时间,则返回上一个闹钟剩余的时间,否则返回0

出错 -1

pause()

pause()函数是用于将调用进程挂起直至收到信号为止。

#include<unistd.h>

int pause(void);

返回值:-1,并且把errno值设为EINTR

3.3.2.3 软件方式产生信号

kill()

可以发送信号给进程或进程组。注意:它不仅可以终止进程(SIGTERM信号),也可以向进程发送其他信号。

#include<signal.h>

#include<sys.types.h>

int kill(pid_t pid,int sig);

参数 pid:正数:要接收信号的进程的进程号

                      0:信号被发送到所有和pid进程在同一个进程组的进程

                     -1:信号发给所有的进程表中的进程(除了进程号最大的进程外)

        sig:信号

返回值 成功:0   出错:-1

raise()

       与kill()不同,只允许进程向自身发送信号

#include<signal.h>

#include<sys/types.h>

int raise(int sig);

参数 sig:信号

返回值 成功:0   出错:-1

3.3.3 捕获信号

#include<signal.h>

typedef void(*sighandler_t)(int);

sighandler_t signal(int signum,sighandler_t handler);

参数 signum:指定信号

        handler:SIG_IGN:忽略该信号

                       SIG_DFL:采用系统默认方式处理信号

                       自定义的信号处理函数指针

返回值 成功:设置之前的信号处理方式

          出错:-1

1.执行默认操作

2.忽略信号,即对信号不做任何处理,有两个信号不能忽略       SIGKILL   SIGSTOP

3.安装信号,获得信号之后,我们要去执行自定义函数

4、systemV进程间通信方式

4.1 systemV IPC基础

       systemV提供的IPC机制主要有消息队列,信号量和共享内存3种机制,和文件一样,IPC在使用前必须先创建,每种IPC都有特定的生产者、所有者和访问权限,使用ipcs命令可以查看当前系统正在使用的IPC工具。

       由此可以看出一个IPC工具至少包含key值、ID值、拥有者、权限和使用大小等信息,如果需要手工删除某个IPC机制,可以使用ipcrm命令。

4.2 key值和ID值

Linux系统为每个IPC机制都分配了唯一的ID值,所有针对该IPC机制的操作都使用该ID值。因此,通信的双方都需要通过某个办法来获得ID值。为解决这一问题,IPC在实现时约定使用key值作为参数创建,如果在创建时使用相同的key值将得到同一个IPC对象的ID值,这样就保证了双方可以获取用于传递数据的IPC机制和ID值。key值为一个32位的整型数据。

4.2.1如何获得key值

Linux提供函数ftok()来创建key值

#include<sys/types.h>

#include<sys/ipc.h>

key_t ftok(cinst char *pathname,int proj_id);

参数1 文件路径名,一般情况下使用当前路径

参数2 一个整数,随机值

4.3 消息队列

4.3.1 特点

1.消息队列由

4.3.2相关函数

4.3.2.1创建消息队列

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/msg.h>

int msgget(key_t key,int msgflg);

参数1 ftok()获得key值,key值相,ID值一定一致  IPC_PRIVATE表示新建一个消息队列

参数2 权限  IPC_CREAT|0777 表示消息队列不存在,则新建,存在则返回

                      IPC_EXCL 表示消息队列存在则出错

4.3.2.2删除消息队列

4.3.2.3发送和接收消息队列

4.4共享内存

4.4.1特点

1.共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝

2.由于多进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等

4.4.2相关函数

1.创建共享内存

2.映射共享内存

即把指定的共享内存映射到进程的地址空间用于访问

3.向共享内存写入数据

4.撤销映射

5.删除共享内存

5、信号量不能传递数据,一般和共享内存配合使用,实现共享内存同步

无名信号量

       sem_t     sem1      信号量是共享的

       sem_init()      初始化信号量

       sem_wait()     P操作    sem>0   -1操作 

       sem_post()

有名信号量

sem_wait (P操作)

Sem_post(V操作)

5.进程间通信方式比较

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值