Linux线程间通信之信号量(十九)
1.信号量
信号量概述 信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。 编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于 0 时,则可以访问,否则将阻塞。 PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1。 信号量主要用于进程或线程间的同步和互斥这两种典型情况。 信号量数据类型为:sem_t。
信号量用于互斥:
信号量用于同步:
2.初始化信号量函数
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:
创建一个信号量并初始化它的值。一个无名信号量在被使用前必须先初始化。
参数:
sem:信号量的地址。
pshared:等于 0,信号量在线程间共享(常用);不等于0,信号量在进程间共享。
value:信号量的初始值。
返回值:
成功:0。
失败:-1。
3.信号量减一函数
int sem_wait(sem_t *sem);
功能:
将信号量减一,如果信号量的值为0 则阻塞,大于0可以减一。
参数:
sem:信号量的地址。
返回值:
成功:0。
失败:-1。
4.尝试对信号量减一函数
int sem_trywait(sem_t *sem);
功能:
尝试将信号量减一,如果信号量的值为0 不阻塞,立即返回 ,大于0可以减一。
参数:
sem:信号量的地址。
返回值:
成功:0。
失败:-1。
5.信号量加一函数
int sem_post(sem_t *sem);
功能:
将信号量加一。
参数:
sem:信号量的地址。
返回值:
成功:0。
失败:-1。
6.销毁信号量函数
int sem_destroy(sem_t *sem);
功能:
销毁信号量。
参数:
sem:信号量的地址。
返回值:
成功:0。
失败:-1。
7.参考代码
//=============================================================================
// File Name : thread_semaphore.c
// Author : FengQQ
//
// Description : 信号量
// Annotation :
//
// Created by FengQQ. 2020-10-05
//=============================================================================
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <semaphore.h>
sem_t sem1,sem2;
char ch='a';
//---------------线程1入口函数---------------
void *pthread1_callback(void *arg)
{
while(1)
{
sem_wait(&sem2); //sem2信号量减一
ch++;
sleep(1);
sem_post(&sem1); //sem1信号量加一
}
}
//---------------线程2入口函数---------------
void *pthread2_callback(void *arg)
{
while(1)
{
sem_wait(&sem1); //sem1信号量减一
putcharputchar(ch); //输出字符
fflush(stdout); //清除读写缓冲区
sem_post(&sem2); //sem2信号量加一
}
}
int main(int argc,char *argv[])
{
int ret;
pthread_t ptid1,ptid2;
sem_init(&sem1,0,1); //初始化信号量sem1
sem_init(&sem2,0,0); //初始化信号量sem2
ret = pthread_create(&ptid1,NULL,pthread1_callback,NULL); //创建线程1
if(ret != 0)
{
printf("create new pthread1 failed...\r\n");
return -1;
}
ret = pthread_create(&ptid2,NULL,pthread2_callback,NULL); //创建线程2
if(ret != 0)
{
printf("create new pthread2 failed...\r\n");
return -1;
}
ret = pthread_join(ptid1,NULL); //回收线程1资源
if(ret != 0)
{
printf("pthread1 join failed...\r\n");
}
ret = pthread_join(ptid2,NULL); //回收线程2资源
if(ret != 0)
{
printf("pthread2 join failed...\r\n");
}
sem_destroy(&sem1); //销毁信号量sem1
sem_destroy(&sem2); //销毁信号量sem2
return 0;
}