This is os_3 code
Pipe community
Q
实现一个管道通信程序:
由父进程创建一个管道,然后再创建 3 个子进程,并由这三个子进程利用管道与父进程之间进行通信:子进程发送信息,父进程等三个子进程全部发完消息后再接收信息。通信的具体内容可根据自己的需要随意设计,要求能试验阻塞型读写过程中的各种情况,测试管道的默认大小,并且要实现进程间对管道的互斥访问。运行程序,观察各种情况下,进程实际读写的字节数以及进程阻塞唤醒的情况
!
在这个实验开始前 我们先清楚几个函数:
sem_init
用于创建信号量,其原型如下:int sem_init(sem_t *sem, int pshared, unsigned int value);
该函数初始化由 sem 指向的信号对象,并给它一个初始的整数值 value
pshared 控制信号量的类型,值为 0 代表该信号量用于多线程间的同步,值如果大于 0 表示可以共享,用于多个相关进程间的同步
sem_wait
sem_wait 是一个阻塞的函数,测试所指定信号量的值,它的操作是原子的。若 sem value > 0,则该信号量值减去 1 并立即返回。若sem value = 0,则阻塞直到 sem value > 0,此时立即减去 1,然后返回
sem_post
把指定的信号量 sem 的值加 1,唤醒正在等待该信号量的任意线程。
sem_getvalue
获取信号量 sem 的当前值,把该值保存在 sval,若有 1 个或者多个线程正在调用 sem_wait 阻塞在该信号量上,该函数返回阻塞在该信号量上进程或线程个数。
sem_destroy
顾名思义,该函数用于对用完的信号量的清理,成功返回1,失败返回0
pipe.c
1 |
|
pipe_max.c
1 |
|
Message queue
Q
利用 linux 的消息队列通信机制实现两个线程间的通信:
编写程序创建三个线程:sender1 线程、sender2 线程和 receive 线程,三个线程的功能描述如下:
① sender1 线程:运行函数 sender1(),它创建一个消息队列,然后,等待用户通过终端输入一串字符,将这串字符通过消息队列发送给 receiver 线程;可循环发送多个消息,直到用户输入 exit 为止,表示它不再发消息,最后向 receiver 线程发送消息 end1 ,并且等待 receiver 的应答,等到应答消息后,将接收到的应答信息显示在终端屏幕上,结束程序的运行。
② sender2 线程:运行函数 sender2(),它创建一个消息队列,然后,等待用户通过终端输入一串字符,将这串字符通过消息队列发送给 receiver 线程;可循环发送多个消息,直到用户输入 exit 为止,表示它不再发消息,最后向 receiver 线程发送消息 end2 ,并且等待 receiver 的应答,等到应答消息后,将接收到的应答信息显示在终端屏幕上,结束程序的运行。
③ receiver 线程运行 receive(),它通过消息队列接收来自 sender1 和 sender2 两个线程的消息,将消息显示在终端屏幕上,当收到内容为 end1 的消息时,就向 sender1 发送一个应答消息 over1 ;当收到内容为 end2 的消息时,就向 sender2 发送一个应答消息 over2 ;消息收完后删除消息队列。使用合适的信号量机制实现三个线程之间的同步与互斥。
!
pthread_join()函数原型:int pthread_join(pthread_t thread, void **retval);
args:
pthread_t thread: 被连接线程的线程号
void **retval : 指向一个指向被连接线程的返回码的指针的指针
return:
线程连接的状态,0是成功,非0是失败
当调用 pthread_join() 时,当前线程会处于阻塞状态,直到被调用的线程结束后,当前线程才会重新开始执行。
msg_queue.c
1 |
|
in the end
其实我觉得这个核心要明白为啥要阻塞发送和阻塞接收,以及怎样阻塞的 这样就达到了这个实验的目的
Memory share
Q
利用 linux 的共享内存通信机制实现两个进程间的通信:
编写程序 sender,它创建一个共享内存,然后等待用户通过终端输入一串字符,并将这串字符通过共享内存发送给 receiver;最后,它等待 receiver 的应答,等到应答消息后,将接收到的应答信息显示在终端屏幕上,删除共享内存,结束程序的运行。编写 receiver 程序,它通过共享内存接收来自 sender 的消息,将消息显示在终端屏幕上,然后再通过该共享内存向 sender 发送一个应答消息 over ,结束程序的运行。使用 有名信号量 或 System V 信号量实现两个进程对共享内存的互斥及同步使用。
init.c
1 |
|
sender.c
1 | key_t key; |
receiver.c
1 | key_t key; |
函数check_value()的必要性?
check_value(sem_t *semtmp, int style) 可以判断是否有 线程/进程 阻塞在 sem_wait(semtmp) 上,即 check_value(recv_psx,0) 可以判断是否有线程/进程在 读取 ,若没有,才对 recv_psx 进行 V原语操作 ,释放 读取 的资源,允许 读取 。保证了同时只能有一个线程/进程在 读取 。