课上代码:
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;
}
效果图: