课上代码:
sem.h
#ifndef _SEM_H_
#define _SEM_H_int open_sem(int semcount);
int P(int semid,int semno);
int V(int semid,int semno);
int del_sem(int semid);#endif
sem.c
#include <myhead.h>
union semun
{int val;struct semid_ds *buf;unsigned short *array;struct seminfo *__buf;
};
int init_semno(int semid, int semno)
{union semun buf;printf("请输入要给编号为%d的灯设置的值:", semno);scanf("%d", &buf.val);if (semctl(semid, semno, SETVAL, buf) == -1){perror("semctl error");return -1;}return 0;
}
int open_sem(int semcount)
{key_t key = -1;if ((key = ftok("/", 's')) == -1){perror("ftok error");return -1;}int semid = -1;if ((semid = semget(key, semcount, IPC_CREAT | IPC_EXCL | 0664)) == -1){if (errno == EEXIST){semid = semget(key, semcount, IPC_CREAT | 0664);return semid;}perror("semget error");return -1;}for (int i = 0; i < semcount; i++){init_semno(semid, i);}return semid;
}
int P(int semid, int semno)
{struct sembuf buf;buf.sem_num = semno;buf.sem_op = -1;buf.sem_flg = 0;if (semop(semid, &buf, 1) == -1){perror("P error");return -1;}return 0;
}
int V(int semid, int semno)
{struct sembuf buf;buf.sem_num = semno;buf.sem_op = 1;buf.sem_flg = 0;if (semop(semid, &buf, 1) == -1){perror("V error");return -1;}return 0;
}
int del_sem(int semid)
{if (semctl(semid, 0, IPC_RMID) == -1){perror("delete error");return -1;}return 0;
}
shmsnd.c
#include <myhead.h>
#include"sem.h"
#define PAGE_SIZE 4096
int main(int argc, char const *argv[])
{int semid=open_sem(2);key_t key = -1;if ((key = ftok("/", 's')) == -1){perror("ftok error");return -1;}printf("key =%d\n", key);int shmid = -1;if ((shmid = shmget(key, PAGE_SIZE, IPC_CREAT | 0664)) == -1){perror("shmget error");return -1;}printf("shmid =%d\n", shmid);char *addr = NULL;if ((addr = shmat(shmid, NULL, 0)) == (void *)-1){perror("shmat error");return -1;}printf("addr =%p\n", addr);while (1){P(semid,0);printf("请输入:>>>");fgets(addr, PAGE_SIZE, stdin);addr[strlen(addr) - 1] = 0;printf("数据输入成功\n");V(semid,1);if (strcmp(addr, "quit") == 0){break;}}if (shmdt(addr) == -1){perror("shmdt error");return -1;}if (shmctl(shmid, IPC_RMID, NULL) == -1){perror("shmctl error");}return 0;
}
shmrcv.c
#include <myhead.h>
#include"sem.h"
#define PAGE_SIZE 4096
int main(int argc, char const *argv[])
{int semid = open_sem(2);key_t key = -1;if ((key = ftok("/", 's')) == -1){perror("ftok error");return -1;}printf("key =%d\n", key);int shmid = -1;if ((shmid = shmget(key, PAGE_SIZE, IPC_CREAT | 0664)) == -1){perror("shmget error");return -1;}printf("shmid =%d\n", shmid);char *addr = NULL;if ((addr = shmat(shmid, NULL, 0)) == (void *)-1){perror("shmat error");return -1;}printf("addr =%p\n", addr);while (1){P(semid, 1);printf("收到的数据为:%s\n", addr);if (strcmp(addr, "quit") == 0){break;}V(semid, 0);}if (shmdt(addr) == -1){perror("shmdt error");return -1;}return 0;
}
效果图: