#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/sem.h>
int fd[2];
int semid;
union semun{
int val;
struct semid_ds *ds;
unsigned short *array;
};
void init_sem()
{
if((semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0777)) < 0){
perror("semget error");
exit(1);
}
}
void init_pipe()
{
if(pipe(fd) < 0){
perror("create pipe error");
exit(1);
}
}
void wait_pipe()
{
char c;
if(read(fd[0], &c, sizeof(char)) < 0){
perror("read error");
exit(1);
}
}
void wait_sem()
{
struct sembuf ops = {
0, -1
};
semop(semid, &ops, 1);
}
void notify_pipe()
{
char c = 'c';
if(write(fd[1], &c, sizeof(char)) != sizeof(char)){
perror("write error");
exit(1);
}
}
void notify_sem()
{
struct sembuf ops = {
0, 1, IPC_NOWAIT
};
semop(semid, &ops, 1);
}
void destroy_pipe()
{
close(fd[0]);
close(fd[1]);
}
void destroy_sem()
{
semctl(semid, 0, IPC_RMID, NULL);
}
int main()
{
//创建共享内存...
int shmid;
if((shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | IPC_EXCL | 0777)) < 0){
perror("shmget error");
exit(1);
}
//init_pipe();
init_sem();
pid_t pid = fork();
if(pid > 0){
//父进程,映射共享内存
int *shmaddr = shmat(shmid, 0, 0);
if(shmaddr == (int *) -1){
perror("shmat error");
exit(1);
}
//向共享内存中写入数据(通过操作共享内存的映射地址即可)
*shmaddr = 100;
*(shmaddr + 1) = 200;
//解除共享内存绑定
shmdt(shmaddr);
sleep(6);
//通知子线程
//notify_pipe();
notify_sem();
//等待子进程结束
wait(0);
//删除共享内存
shmctl(shmid, IPC_RMID, NULL);
//回收管道
//destroy_pipe();
destroy_sem();
}else if(pid == 0){
//等待父进程写入完成
//wait_pipe();
printf("wait for parent...\n");
wait_sem();
int *shmaddr = shmat(shmid, 0, 0);
if(shmaddr == (int *) -1){
perror("shmat error");
exit(1);
}
int start = *shmaddr;
int end = *(shmaddr + 1);
printf("start = %d, end = %d\n", start, end);
shmdt(shmaddr);
//destroy_pipe();
}else{
perror("fork error");
exit(1);
}
return 0;
}