【Linux】 信号量sem

1.信号量结构体


typedef union
{
  char __size[__SIZEOF_SEM_T];
  long int __align;
} sem_t;

2.常用函数

/*breaf: 创建一个信号量*/
//pshared 为0代表此信号量为局部信号量
int sem_init(sem_t *sem, int pshared, unsigned int value);

/*breaf: 信号量值(初值必须大于1)减1 */
int sem_wait(sem_t *sem);

/*breaf: 信号量值加1 */
int sem_post(sem_t *sem);

/*breaf: 清理信号量 */
int sem_destroy(sem_t *sem);

3.简单示例(涉及线程部分,可看我上一篇博客)


#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"
#include "semaphore.h"

void *thread_funtion(void *arg);
sem_t bin_sem;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];


int main()
{
    int res;
    pthread_t a_thread;
    void *thread_result;

    //1.创建一个局部信号量
	res = sem_init(&bin_sem, 0, 0);  
    if(res != 0){  printf("semphare init fail");  }

    //2.创建一个线程
    res = pthread_create(&a_thread, NULL, thread_funtion, NULL);
    if(res != 0){  printf("error create thread");  }

    //3.从键盘输入任意字符
    printf("please press keyborad!!! end with button 'end'\r\n ");
    while(strncmp("end", work_area, 3) != 0){
		fgets(work_area, WORK_SIZE, stdin);//从键盘读取文本,并放入工作区work_area数组之中
		sem_post(&bin_sem); //bin_sem+1
	}


    //4.等待线程结束
    printf("\n thread waiting for finish \n"); 
    res = pthread_join(a_thread, &thread_result);//thread_result == Thread_A return  "Thank you using CPU!!!!!!"
    if(res != 0){  printf("error thread join "); }
    printf("thread joined, it returned %s ", (char*)thread_result);

    //5.销毁信号量
    sem_destroy(&bin_sem);


}


void *thread_funtion(void* arg)
{
    printf("111\n");
    sem_wait(&bin_sem);
    printf("222");
    while(strncmp("end", work_area, 3) != 0){//任意按键输入,以end键结束
		printf("you have input %zu characters\n", strlen(work_area)-1); //%zu 输出size_t类型的数据
		sem_wait(&bin_sem); 
	}
    //printf("333");

}



4.运行结果

5.结合代码,分析上述流程。

【1】创建信号量(初值为0),线程(线程A)。

【2】main函数的线程(主线程)运行至等待键盘输入字符的地方(打印出了please press keyborad!! end with button 'end'),同时紧接着运行至线程A(打印出了111),但此时键盘没有任何的输入,信号量为0,于是线程A运行至sem_wait(&bin_sem);处,由于信号量为0,于是不会继续往下执行(没有打印出222)

【3】键盘输入“abc+回车”,那么在主线程中则会调用sem_post(&bin_sem)函数,那么信号量加1,变为非0值。程序运行至fget()等待键盘的输入

 线程A此时停在sem_wait(&bin_sem);由于信号量变为非0值,那么就会执行while()里面的打印函数(打印了you have input 3 characters),然后再调用sem_wait(&bin_sem);于是bin_sem变为0,线程A则会停在此处(没有一直打印you have input 3 characters,即可证明)

【4】键盘输入"def+回车",即重复过程上述【3】

5】键盘输入"end+回车",主线程退出while,并且等待线程A结束(即退出线程A的while),最后打印main()剩下的部分

---------------------------------------------------------------------------2021.4.27更新------------------------------------------------------------------------------------------------------------------------------------------------

信号量常用于两个线程之间。现有两个线程A和B,在B中程序会卡在sem_wait(&bin_sem)处,而当A调用了sem_post(&bin_sem)之后,B 就会解除阻塞,继续向下运行。就是这么个简单的逻辑。。。。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值