进程间通信—共享内存、信号量

/*************************************************************************
    > 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;
}
/*
 * 信号量能实现同步也与对信号量的操作是原子操作有关
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值