Linux关于信号量

信号量概念

Dijkstra提出的“信号量”概念是共发程序设计领域的一项重大进步 信号量是一种变量,它只能取正整数值,对这些正整数只能进行两种操作:等待和信号 用两种记号来表示信号量的这两种操作:     P(semaphore variable) 代表等待     V(semaphore variable) 代表信号

信号量操作

首先我们对信号量进行封装:

//对信号量中要用到的联合体进行声明
union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           }
//错误打印

void error_exit(char *errorinfo)
{
    printf("%s\n",errorinfo);
    exit(EXIT_FAILURE);
}

//信号量创建
int  sem_create(key_t key,int nsems)
{
  int semid = semget(key,nsems,IPC_CREAT|0766);
  if(semid <0)
  {
      error_exit("creat sem error");
  }
  return semid;
}

//信号量的打开

int sem_myopen(key_t key)
{
  int semid = semget(key,0,0);
  if(semid <0)
  {
      error_exit("creat sem error");
  }
  return semid;
}

//信号量删除
int sem_delete(int semid)
{
  int ret = semctl(semid,0,IPC_RMID);
  if(ret<0)
  {
      error_exit("delete sem error");
  }
  return ret;
}

//信号量设置里面的值

int sem_setval(int semid,int nsempos,int val)
{
    union semun arg;
    arg.val=val;
    int ret=semctl(semid,nsempos,SETVAL,arg); 
    if(ret<0)
    {
       error_exit("set value error");
    }
    return ret;
}

//信号量获取里面的值
int sem_getval(int semid,int nsempos)
{
    int value=semctl(semid,nsempos,GETVAL); 
    if(value<0)
    {
       error_exit("get value error");
    }
    return value;
}

//信号量设置
int sem_setall(int semid,unsigned short*values)
{
     union semun arg;
     arg.array=values;
    int ret=semctl(semid,0,SETVAL,values); 
    if(ret<0)
    {
       error_exit("set all error");
    }
    return ret;
}

//信号量获取
int sem_getall(int semid,unsigned short*values)
{
     union semun arg;
     arg.array=values;
    int ret=semctl(semid,0,GETVAL,values); 
    if(ret<0)
    {
       error_exit("set all error");
    }
    return ret;
}

//信号量V操作
int sem_v(int semid,int npos)
{
   struct sembuf buf={npos,1,0};
   int ret=semop(semid,&buf,1);
   if (ret<0)
   {
        error_exit("sem p error");
   }
   return ret;
}

//信号量P操作
int sem_p(int semid,int npos)
{
   struct sembuf buf={npos,-1,0};
   int ret=semop(semid,&buf,1);
   if (ret<0)
   {
        error_exit("sem p error");
   }
   return ret;
}

简单使用上面封装的函数实现 父子进程上锁

int main()
{
    int semid= sem_create((key_t)0002,1);
    sem_setval(semid,0,0);
    int pid =fork();
    //父进程
    if(pid>0)
    {
        while(1)
        {
            printf("parent working\n");
            sleep(5);
            sem_v(semid,0);
        }
    }
    //子进程
    else if(pid==0)
    {
       while(1)
       {
           printf("child wait\n");
           sem_p(semid,0);
           printf("child working\n");
       }
    }
    else
    {
       perror("fork error\n");
    }
    return 0;
}

实现结果:(每次执行完一个进程才会执行下一个进程,可用于两进程协同处理事情的时候进行使用)

使用以上封装的函数实现多进程p和v的操作

int main()
{
     int semid=sem_create((key_t)0001,1);
     sem_setval(semid,0,10);
     fork();
     fork();
     fork();
     fork();
     fork();
     fork();
     sleep(1);
     printf("my name is %d\n",getpid());
     sem_p(semid,0);
     printf("%d get\n",getpid());
     sleep(5);
     printf("%d done\n",getpid());
     sem_v(semid,0);
     return 0;
}

结果:

上面结果:fork6次,总共64个进程,如同64个人练车一样,但是只有10辆车(set_value的第三个参数设置了10),使用p操作代表车被用了一辆,v代表车使用完让出来给别人用,这就是生产者和消费者模型,进行资源保护

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值