操作系统原理作业(三):IPC编程问题

作业题目

有一个仓库,可以存放 A 和 B 两种产品,仓库的存储空间足够大,但要求:
(1)一次只能存入一种产品(A 或 B);
(2)-N < (A 产品数量 - B 产品数量) < M。
其中, N 和 M 是正整数。试在POSIX系统平台上实现产品A和产品B的入库过程。

伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
typedef int semaphore;
semaphore mutex = 1; //互斥信号量
semaphore a = M - 1//存放A的资源信号量,初值为M-1
semaphore b = N - 1; //存放B的资源信号量,初值为N-1
PA:
while (true)
{
P(&a);
P(&mutex);
A 入库;
V(&mutex);
V(&b);
}
PB:
while (true)
{
P(&b);
P(&mutex);
B 入库;
V(&mutex);
V(&a);
}

完整代码

init.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include "myipc.h"
int main(int argc, char *argv[])
{
int i,producer_pid,consumer_pid,item,shmid;
//mutex为互斥信号量,a为存放A的资源信号量,b为存放B的资源信号量
semaphore mutex, a, b;
union semun sem_union;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
//判断mutex、a、b信号量是否创建成功
if ( (mutex=semget((key_t)KEY_MUTEX,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (a = semget((key_t)KEY_EMPTY,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (b = semget((key_t)KEY_FULL,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (shmid = shmget((key_t)KEY_SHM,sizeof(struct shared_use_st),0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create shared memory!");
exit(EXIT_FAILURE);
}
//判断mutex、a、b信号量是否创建成功
sem_union.val = 1; //将互斥信号量初始化为1
if (semctl(mutex, 0, SETVAL, sem_union) == -1) {
fprintf(stderr,"Failed to set semaphore!");
exit(EXIT_FAILURE);
}
sem_union.val = 10; //将产品B的资源信号量初始化为10
if (semctl(b, 0, SETVAL, sem_union) == -1) {
fprintf(stderr,"Failed to set semaphore!");
exit(EXIT_FAILURE);
}
sem_union.val = 10; //将产品A的资源信号量初始化为10
if (semctl(a, 0, SETVAL, sem_union) == -1) {
fprintf(stderr,"Failed to set semaphore!");
exit(EXIT_FAILURE);
}
if ( (shared_memory = shmat(shmid,(void *)0,0) ) == (void *)-1) {
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
shared_stuff = (struct shared_use_st *)shared_memory;
for(i=0;i<BUFFER_SIZE;i++)
{
shared_stuff->buffer[i] = 0;
}
shared_stuff -> lo = 0;
shared_stuff -> hi = 0;
shared_stuff -> cur = 0;
exit(EXIT_SUCCESS);
}

proa.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include "myipc.h"
int main(int argc, char *argv[])
{
int i,item,shmid;
//mutex为互斥信号量,a为存放A的资源信号量,b为存放B的资源信号量
semaphore mutex, a, b;
union semun sem_union;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
//判断mutex、a、b信号量是否创建成功
if ( (mutex=semget((key_t)KEY_MUTEX,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (a = semget((key_t)KEY_EMPTY,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (b = semget((key_t)KEY_FULL,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (shmid = shmget((key_t)KEY_SHM,sizeof(struct shared_use_st),0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create shared memory!");
exit(EXIT_FAILURE);
}
if ( (shared_memory = shmat(shmid,(void *)0,0) ) == (void *)-1) {
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
shared_stuff = (struct shared_use_st *)shared_memory;
//产品A的入库过程
for(i=0;i<30;i++)
{
item = ++(shared_stuff->cur);
sleep(1); //等待1s
printf("Putting product A of No.%d\n", item); //输出正在入库的产品A的序号
sem_p(a); //将产品A的资源信号量减1
sem_p(mutex); //获取互斥锁
(shared_stuff->buffer)[(shared_stuff->hi)] = item;
(shared_stuff->hi) = ((shared_stuff->hi)+1) % BUFFER_SIZE;
printf("The number of A in resposity is %d\n", item); //输出仓库中产品A的数量
sem_v(mutex); //释放互斥锁
sem_v(b); //将产品B的资源信号量加1
}
if (shmdt(shared_memory) == -1) {
fprintf(stderr, "shmdt failed\n");
exit(EXIT_FAILURE);
}
printf("Finish!\n");
getchar();
exit(EXIT_SUCCESS);
}

prob.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include "myipc.h"
int main(int argc, char *argv[])
{
int i,item,shmid;
//mutex为互斥信号量,a为存放A的资源信号量,b为存放B的资源信号量
semaphore mutex, a, b;
union semun sem_union;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
//判断mutex、a、b信号量是否创建成功
if ( (mutex=semget((key_t)KEY_MUTEX,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (a = semget((key_t)KEY_EMPTY,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (b = semget((key_t)KEY_FULL,1,0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create semaphore!");
exit(EXIT_FAILURE);
}
if ( (shmid = shmget((key_t)KEY_SHM,sizeof(struct shared_use_st),0666|IPC_CREAT)) == -1 ) {
fprintf(stderr,"Failed to create shared memory!");
exit(EXIT_FAILURE);
}
if ( (shared_memory = shmat(shmid,(void *)0,0) ) == (void *)-1) {
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
shared_stuff = (struct shared_use_st *)shared_memory;
//产品B的入库过程
for(i=0;i<30;i++)
{
sem_p(b);
sem_p(mutex); //获取互斥信号量
item = shared_stuff->buffer[shared_stuff->lo];
(shared_stuff->buffer)[(shared_stuff->lo)]=0;
(shared_stuff->lo) = ((shared_stuff->lo)+1) % BUFFER_SIZE;
printf("Putting product A of No.%d\n", item); //输出正在入库的产品B的序号
sem_v(mutex); //释放互斥锁
sem_v(a);
printf("The number of B in resposity is %d\n", item); //输出仓库中产品B的数量
sleep(2); //等待2s
}
if (shmdt(shared_memory) == -1) {
fprintf(stderr, "shmdt failed\n");
exit(EXIT_FAILURE);
}
printf("Finish!\n");
getchar();
exit(EXIT_SUCCESS);
}

makefile文件

1
2
3
4
5
6
default: myipc init.c proa.c prob.c
gcc -o init myipc.o init.c
gcc -o proa myipc.o proa.c
gcc -o prob myipc.o prob.c
myipc: myipc.c
gcc -c myipc.c

运行结果

产品A的入库情况

产品B的入库情况

源代码下载

完整的源代码可以移步至我的 Github个人主页 进行查看和下载^-^。

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章