当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

一个包含了信号、信号量、共享内存的例子

发表于: 2014-11-06   作者:cuiyadll   来源:转载   浏览次数:
c
摘要: 一个包含了信号、信号量、共享内存的例子(转) #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #define
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define SHMKEY1 (key_t)0x10
#define SHMKEY2 (key_t)0x15

#define SEMKEY  (key_t)0x20

#define SIZ 5*BUFSIZ


#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define ERR ((struct databuf*)-1)
//p1,v1是针对第一个信号进行的操作
struct sembuf p1 = {0, -1, 0};
struct sembuf v1 = {0, 1, 0};
//p2,v1是针对第二个信号进行的操作
struct sembuf p2 = {1, -1, 0};
struct sembuf v2 = {1, 1, 0};
//表示两个内存共享区和一个信号量集合
static int shmid1, shmid2, semid;
//作为暂时存放数据的结构体
struct databuf
{
    int d_nread;
    char d_buf[SIZ];
};


void fatal(char *mes)
{
      perror(mes);
      exit (1);
}
/**创建两个共享内存,并且分别shmat给两个参数*/
void getshm (struct databuf **p1, struct databuf **p2)
{      //创建共享内存
      if ((shmid1=shmget(SHMKEY1, sizeof(struct databuf), 0600|IFLAGS)) < 0)
      {
        fatal ("shmget");
      }

      if ((shmid2=shmget(SHMKEY2, sizeof(struct databuf), 0600|IFLAGS)) < 0)
      {
        fatal ("shmget");
      }
      //映射
      if ((*p1=(struct databuf*)(shmat(shmid1, 0, 0))) == ERR)
      {
        fatal("shmat");
      }

      if((*p2=(struct databuf*)(shmat(shmid2, 0, 0))) == ERR)
      {
        fatal("shmat");
      }

}

int getsem()
{
         //获取一个长度为2的信号量集合;
          if ((semid=semget(SEMKEY, 2, 0600|IFLAGS)) < 0)
          {
          fatal("segmet");
          }
          //初始化信号量,假定第一个信号灯没有资源
          if (semctl(semid, 0, SETVAL, 0) < 0)
          {
           fatal ("semctl");
          }
          //第二个有信息,如果两个信号都没有资源,将会出现死锁
          //书上该处有问题
          if (semctl(semid, 1, SETVAL, 1) < 0)
          {
            fatal ("semctl");
          }

          return (semid);
}
//回收共享两个内存区和一个信号量集合
void myremove()
{
      if (shmctl(shmid1, IPC_RMID, NULL) < 0)
      {
        fatal("shmctl");
      }
      if (shmctl(shmid2, IPC_RMID, NULL) < 0)
      {
        fatal("shmctl");
      }
      if (semctl(semid, 0, IPC_RMID, NULL) < 0)
         fatal("semctl");
       
      exit(0);
}

void reader(int semid, struct databuf *buf1, struct databuf *buf2)
{
      for(;;)
      {
       unsigned short val= semctl(semid,0,GETVAL,null);
       if(val<=0)
       {
         semop(semid,&v1,1);
       }
       else{
         //申请第一个信号灯资源
         semop(semid, &p1, 1)
       }
       //从键盘读入数据,放在buf1->d_buf,
       //read第一个参数是文件描述符,其中0表示从终端输入:如键盘
       buf1->d_nread = read(0, buf1->d_buf, SIZ);
       //v操作,释放第一个信号灯资源   
       semop(semid, &v1, 1);
      
       //p操作,申请第二个信号灯资源,若没有资源,则阻塞进程直到有资源.
       semop(semid, &p2, 1);
     
       buf2->d_nread = read(0, buf2->d_buf, SIZ);
      //v操作,释放第二个信号灯资源
       semop(semid, &v2, 1);
     }
            
}

void writer(int semid, struct databuf *buf1, struct databuf *buf2)
{
      for(;;)
      {
        //p操作,等待第一个信号的资源    
        semop(semid, &p1, 1);
        //1代表输出到屏幕
        write(1, buf1->d_buf, buf1->d_nread);
        //释放第一个信号灯资源
        semop(semid, &v1, 1);
     
        //p操作,申请第二个信号灯资源,若没有资源,则阻塞进程直到有资源.
        semop(semid, &p2, 1);
      
        write(1, buf2->d_buf, buf2->d_nread);
 
        semop(semid, &v2, 1);
                                                          }
}

int main()
{
      int semid, pid;
       
      struct databuf *buf1, *buf2;
     
      semid = getsem();
      getshm (&buf1, &buf2);

      switch(pid=fork())
      {
        case -1:
            fatal("fork");
            break;
        case 0:
            writer(semid, buf1, buf2);
            break;
        default:
       
        //在主进程中把中断程序的ctrl+c和myremove函数建立联系,
        //来回收系统资源:共享内存区,信号量.
        signal (SIGINT, myremove);
        reader(semid, buf1, buf2);
        break;
     }
      exit(0);
}

 

一个包含了信号、信号量、共享内存的例子

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
一. 信号量   l信号量: 解决进程之间的同步与互斥的IPC机制 多个进程同时运行,之间存在关联   
sem1.c 1 #include"unistd.h" 2 #include"string.h" 3 #include"stdio.h" 4 #include"stdlib.h" 5 #
Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:《linux编程从入门到精通》
Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:《linux编程从入门到精通》
0、 信号量 Linux下的信号量和windows下的信号量稍有不同。 Windows Windows下的信号量有一个最大值
0、 信号量 Linux下的信号量和windows下的信号量稍有不同。 Windows Windows下的信号量有一个最大值
生产者消费者问题:该问题描述了两个共享固定大小缓冲区的进程——即所谓的“生产者”和“消费者”
信号量机制 11.1 2 个程序的例子 先看 2 个程序; #include<unistd.h> int main(void) { alla
注意:表述有误! 请以mannul手册为准! -------------------------------------------------------
1、概述   信号量(semaphore)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号