/*************************************************************************
> File Name: test.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Fri 20 Oct 2017 01:49:05 PM CST
************************************************************************/
/*共享内存 信号量实现同步*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<wait.h>
#include<sys/shm.h>/*共享内存*/
#include<sys/sem.h>/*信号量*/
#include<string.h>
#define MAX_SIZE 100
#define SHM_KEY_T 9494/*共享内存键*/
#define SEM_KEY_T 8989/*信号量键*/
struct SHM_BLOCK
{
int semid; /*信号量标识符*/
int datacount;
int beginpos;
int curpos;
char data[MAX_SIZE];
};
/*父子进程函数声明*/
void child_process();
void parent_process();
struct SHM_BLOCK *block;/*指向共享内存的指针*/
struct sembuf buf;/*操作信号量结构体*/
int pid;/*用于存储子进程的pid*/
int shmid;/*共享内存标识符*/
int main(void)
{
/*创建共享内存*/
shmid = shmget(SHM_KEY_T, sizeof(struct SHM_BLOCK), 0666 | IPC_CREAT);
/*将共享内存连接到进程的地址空间*/
block = (struct SHM_BLOCK*)shmat(shmid, (const void*)0, 0);/*最后一个0表示以读写的方式连接共享内存*/
block->semid = semget(SEM_KEY_T, 1, 0666 | IPC_CREAT);/*创建一个信号量*/
block->datacount = 0;
block->beginpos = 0;
block->curpos = 0;
semctl(block->semid, 0, SETVAL, 1);/*初始化信号量为1*/
pid = fork();
if(pid == 0)
child_process();
else
parent_process();
return 0;
}
void child_process()
{
printf("Im child Process pid is %d lets begin do work\n", getpid());
// getchar();
int taskcount = 0;
char task;
// block = (struct SHM_BLOCK*)shmat(SHM_KEY_T, (const void*)0, 0);/*将共享内存连接到进程的地址空间*/
buf.sem_flg = 0;
buf.sem_num = 0;
while(taskcount < 200)
{
//printf("********");
buf.sem_op = -1;
semop(block->semid, &buf, 1);
buf.sem_op = 1;
if(block->datacount == 0)/*共享内存中没有数据*/
{
semop(block->semid, &buf, 1);
continue;
}
// printf("********\n");
block->datacount--;
task = block->data[block->beginpos++];
block->beginpos %= MAX_SIZE;
semop(block->semid, &buf, 1);
taskcount++;
printf("cur task is %d the data is %c\n", taskcount, task);
}
shmdt((const void*)block);
return;
}
void parent_process(void)
{
printf("Im parent Process pid is %d lets begin add work\n", getpid());
// getchar();
buf.sem_flg = 0;
buf.sem_num = 0;
int taskcount = 0;
while(taskcount < 200)/*添加200个任务*/
{
// printf("********");
buf.sem_op = -1;/*信号量减1, 原子操作*/
semop(block->semid, &buf, 1);/*这里信号量减1是为了同步,减1信号量值为0,其他进程就在这里睡眠*/
buf.sem_op = 1;
if(block->datacount >= MAX_SIZE)
{
semop(block->semid, &buf, 1);/*如果共享数据内存满了,则给信号量加1让其他进程读*/
continue;
}
// printf("*******\n");
block->datacount++;/*否则说明共享内存没有满,则往里面 添加任务*/
block->data[block->curpos++] = 'a' + taskcount%26;
block->curpos %= MAX_SIZE;
semop(block->semid, &buf, 1);
taskcount++;
}
/*回收进程资源*/
waitpid(pid, NULL, 0);
/*释放信号信号量和共享内存*/
semctl(block->semid, 0, IPC_RMID);
shmdt((const void*)block);
shmctl(shmid, IPC_RMID, 0);
return;
}
/*
* 信号量能实现同步也与对信号量的操作是原子操作有关
*/
进程间通信—共享内存、信号量
最新推荐文章于 2024-04-26 17:36:11 发布