Linux--信号量


1、信号量概述

信号量广泛用于进程线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。

当信号量值大于 0 时,则可以访问,否则将阻塞。

PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1

号量数据类型为:sem_t

信号量用于互斥:
不管多少个任务互斥 只需要一个信号量。先P 任务 在 V

信号量用于同步:
有多少个任务 就需要多少个信号量。最先执行的任务对应的信号量为1,其他信号量全部为0。每任务先P自己 任务 V下一个任务的信号量

2、信号量的API

1、初始化信号量

#include<semaphore.h>
int sem_init(sem_t* sem,int pshared,unsigned int value)

功能:
        创建一个信号量并初始化它的值。一个无名信号量在被使用前必须先初始化。
参数:
        sem:信号量的地址
        pshared:等于 0,信号量在线程间共享(常用);不等于0,信号量在进程间共享。
        value:信号量的初始值
返回值:
        成功:0
        失败: - 1

2、信号量减一 P操作

int sem_wait(sem_t* sem);

功能:
        将信号量减一,如果信号量的值为0 则阻塞,大于0可以减一
参数:
        信号量的地址
返回值:
        成功返回0 失败返回-1

尝试对信号量减一

int sem_trywait(sem_t* sem);

功能:
        尝试将信号量减一,如果信号量的值为0 不阻塞,立即返回 ,大于0可以减一
参数:
        信号量的地址
返回值:
        成功返回0
        失败返回-1

3、信号量加一 V操作

int sem_post(sem_t* sem);

功能:
        将信号量加一
参数:
        信号量的地址
返回值:
        成功返回0 失败返回-1

4、销毁信号量

int sem_destroy(sem_t* sem);

功能:
        销毁信号量
参数:
        信号量的地址
返回值:
        成功返回0
        失败返回-1

示例代码  信号量用于线程的互斥

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
//定义一个信号量(用于互斥)
sem_t sem;
void my_printf(char* str)
{
     int i = 0;
     while (str[i] != '\0')
     {
          printf("%c", str[i++]);
          fflush(stdout);
          sleep(1);
      }
  return;
}

void* task_fun01(void*arg)

        //P 操作
        sem_wait(&sem);
        my_printf((char *)arg);
        //V 操作 
        sem_post(&sem); 
        return NULL; 
 }
void* task_fun02(void* arg) 

        //P 操作
        sem_wait(&sem); 
        my_printf((char *)arg);
        //V 操作
        sem_post(&sem); 
        return NULL;

void* task_fun03(void* arg) 

          //P 操作
          sem_wait(&sem);
         my_printf((char *)arg); 
         //V 操作
        sem_post(&sem); 
        return NULL; 
 }
int main(int argc,char const* argv[])

      //信号量初始化为1 第二个参数0表示用于线程 
      sem_init(&sem, 0, 1);
      pthread_t tid1, tid2,  tid3;
      pthread_create(&tid1, NULL, task_fun01, "hello");
      pthread_create(&tid2, NULL, task_fun02, " world ");
      pthread_create(&tid3, NULL, task_fun03, " beijing ");
      pthread_join(tid1, NULL);
      pthread_join(tid2, NULL);
      pthread_join(tid3, NULL);
      //销毁信号量 
      sem_destroy(&sem); 
      return 0; 
 }


示例代码 信号量用于线程的同步

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
//定义三个信号量(用于同步)
sem_t sem1;
sem_t sem2;
sem_t sem3;
void my_printf(char* str)
{
     int i = 0;
     while (str[i] != '\0') 
    {
          printf("%c", str[i++]);
          fflush(stdout);
          sleep(1);
      }
  return;
}
void* task_fun01(void*arg){
         //P 操作
        sem_wait(&sem1);
        my_printf((char *)arg);
        //V 操作
         sem_post(&sem2);
         return NULL;
  }
void* task_fun02(void* arg) 

        //P 操作
        sem_wait(&sem2); 
        my_printf((char *)arg);
        //V 操作
        sem_post(&sem3);
         return NULL;
}
 void* task_fun03(void* arg) {
           //P 操作
          sem_wait(&sem3); 
          my_printf((char *)arg);
          //V 操作
          sem_post(&sem1);
         return NULL;
 }
int main(int argc,char const* argv[])
{
       //信号量初始化为1 第二个参数0表示用于线程
      sem_init(&sem1, 0, 1);
      sem_init(&sem2, 0, 0);
      sem_init(&sem3, 0, 0);
      pthread_t tid1, tid2,  tid3;
      pthread_create(&tid1, NULL, task_fun01, "hello");
      pthread_create(&tid2, NULL, task_fun02, " world ");
      pthread_create(&tid3, NULL, task_fun03, " beijing ");
      pthread_join(tid1, NULL);
      pthread_join(tid2, NULL);
      pthread_join(tid3, NULL);
      //销毁信号量
       sem_destroy(&sem);
       return 0;
  }

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容