本关任务:补充完成程序 4-2.c ,实现如下功能:假设有三个并发进程( P、Q、R ),其中 P 负责从输入设备上读取信息并传给 Q , Q 将信息加工后传给 R ,R 负责将信息打印输出。
写出符合下列条件下的并发程序:进程 P、Q 共享一个由 5 个缓冲区组成的缓冲池,进程 Q、R 共享另一个由 8 个缓冲区组成的缓冲池。参考输出如下:
相关知识
为了完成本关任务,你需要掌握:
1.多线程程序如何编译;
2.pthread_create 函数的各个参数的含义是什么;
3.主线程结束时,子线程会被杀死吗。
实验准备
4-2.c文件存放在/data/workspace/myshixun/exp4中。
多线程程序如何编译
用 pthread 库实现的多线程程序,可以使用 gcc 来编译,且需加上 -pthread 参数:
pthread_create 函数的各个参数的含义是什么
该函数的原型和各参数的含义如下:
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr,
(void*)(*start_rtn)(void*), void *arg);
第一个参数为指向线程标识符的指针;
第二个参数用来设置线程属性;
第三个参数是线程运行函数的起始地址;
最后一个参数是运行函数的参数。
主线程结束时,子线程会被杀死吗
是的,如果主线程结束时,子线程还没有结束,那么子线程会被操作系统杀死。可以在主线程中使用 pthread_join 来等待子线程结束。
编程要求
写出符合下列条件下的并发程序:进程 P、Q 共享一个由 5 个缓冲区组成的缓冲池,进程 Q、R 共享另一个由 8 个缓冲区组成的缓冲池。
(请将修改之后的程序 4-2.c 保存到 myshixun 文件夹下再点击评测。)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define LIMIT 20
#define M 5
#define N 8
int buffer1[M], readpos1 = 0, writepos1 = 0;
int buffer2[N], readpos2 = 0, writepos2 = 0;
sem_t empty1, empty2, full1, full2;
void sleep_random(int t) {
sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
void *P(){
int i;
for (i = 0; i < LIMIT; i++){
sleep_random(2);
sem_wait(&empty1);
printf("P sends: %d\n", i+1);
buffer1[writepos1++] = i + 1; /* put to buffer1 */
if (writepos1 >= M)
writepos1 = 0;
sem_post(&full1);
}
}
void *Q(){
int i, data;
for (i = 0; i < LIMIT; i++){
sleep_random(2);
sem_wait(&full1);
data = buffer1[readpos1]; /* get from buffer1 */
buffer1[readpos1++] = - 1;
if (readpos1 >= M)
readpos1 = 0;
sem_post(&empty1);
sem_wait(&empty2);
buffer2[writepos2++] = data; /* put to buffer2 */
if (writepos2 >= N)
writepos2 = 0;
sem_post(&full2);
}
}
void *R(){
int i;
for (i = 0; i < LIMIT; i++){
sleep_random(2);
sem_wait(&full2);
printf("R receives: %d\n", buffer2[readpos2]); /* get from buffer2 */
buffer2[readpos2++] = - 1;
if (readpos2 >= N)
readpos2 = 0;
sem_post(&empty2);
}
}
int main(){
int i;
pthread_t t1, t2;
for (i = 0; i < M; i++)
buffer1[i] = - 1;
for (i = 0; i < N; i++)
buffer2[i] = - 1;
srand((int)time(0));
sem_init(&empty1, 0, 1);
sem_init(&empty2, 0, 1);
sem_init(&full1, 0, 0);
sem_init(&full2, 0, 0);
pthread_create(&t1, NULL, P, NULL);
pthread_create(&t2, NULL, Q, NULL);
R();
return 0;
}