zoukankan      html  css  js  c++  java
  • 信号量

    信号量是不同进程间同步的方式。当几个不同的进程同时访问临界区时,需要同步,防止多个进程同时篡改数据,或者读到脏数据。

    sem_wait对信号量减一,sem_post对信号量加一。

    当初始化信号量值为1时, sem_wait类似于加锁,sem_post类似于释放锁.

    在前面共享内存的代码上稍作修改加上信号量的部分,来保护共享内存。

    其中写共享内存的代码mmap_write.c如下:

    #include <stdio.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <semaphore.h>

    typedef struct _ShareMem{
      char str[128];
      int val;
    }ShareMem;
    #define SHM_STR "FELLOW_SHARE_SOMETHING"
    #define FELLOW_SEM "fellow-sem"
    void main(void)
    {
      int fd;
      ShareMem *mem;
      sem_t *sem;
      if (SEM_FAILED == (sem = sem_open(FELLOW_SEM,O_CREAT, 0666, 1)))//初始化信号量为1    
      {
        printf("sem_open fail:%d,%s ",errno,strerror(errno));
      }

      fd = shm_open(SHM_STR, O_RDWR | O_CREAT, 0666);
      if (-1 == fd)
      {
        printf("shm_open fail:%d,%s ",errno,strerror(errno));
      }
      ftruncate(fd, sizeof(ShareMem));
      mem = mmap(NULL, sizeof(ShareMem), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
      if (mem == MAP_FAILED)
      {
        printf("mmap fail:%d,%s ",errno,strerror(errno));
      }


      printf("share mem:0x%x ", (int)mem);
      sem_wait(sem);
      printf("write share mem now, please wait.... ");
      strncpy(mem->str, "fellow", strlen("fellow"));
      mem->val = 10000;
      sleep(10);
      sem_post(sem);
      printf("write share mem done, you can read now.... ");
      close(fd);
    }

    读共享内存的代码mmap_read.c如下:

    #include <stdio.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>
    #include <semaphore.h>
    typedef struct _ShareMem{
      char str[128];
      int val;
    }ShareMem;
    #define SHM_STR "FELLOW_SHARE_SOMETHING"
    #define FELLOW_SEM "fellow-sem"
    void main(void)
    {
      int fd;
      ShareMem *mem;
      sem_t *sem;
      if (SEM_FAILED == (sem = sem_open(FELLOW_SEM, O_CREAT, 0666, 1)))
      {
      printf("sem_open fail: %d, %s ", errno, strerror(errno));
      }
      int val = -1;
      sem_getvalue(sem, &val);
      printf("sem value:%d ", val);


      fd = shm_open(SHM_STR, O_RDONLY, 0666);
      if (-1 == fd)
      {
        printf("shm_open fail: %d, %s ", errno, strerror(errno));
      }
      mem = mmap(NULL, sizeof(ShareMem), PROT_READ, MAP_SHARED, fd, 0);
      if (MAP_FAILED == mem)
      {
        printf("mmap fail: %d, %s ", errno, strerror(errno));
      }
      sem_wait(sem);
      printf("share mem:0x%x,str:%s,val:%d ", (int)mem, mem->str, mem->val);
      sem_post(sem);
      close(fd);
      munmap(mem, sizeof(ShareMem));
      shm_unlink(SHM_STR);
      sem_unlink(FELLOW_SEM);
    }

    先执行mmap_write,再自行mmap_read,假设写操作经历10s中,可以看到在这10s期间,mmap_read一直在等信号量释放。

  • 相关阅读:
    轻松搞定Ajax(分享下自己封装ajax函数,其实Ajax使用很简单,难是难在你得到数据后来怎样去使用这些数据)
    模块化开发,SesJS简单总结
    轻松实现HTML5时钟(分享下自己对canvas的理解,原来没你想像的那么难哦)
    轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)
    javascript中可处理的浮点数的最高精度(和小数的一些小特性)
    PyLucene检索demo
    PyLucene索引DEMO
    Lucene类介绍
    PyLucene 的安装
    写一个程序,打印数字1到100,3的倍数打印“Fizz”来替换这个数,5的倍数打印“Buzz”,对于既是3的倍数又是5的倍数的数字打印“FizzBuzz”
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6151777.html
Copyright © 2011-2022 走看看