线程同步机制

1)概念:

        同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情

2)信号量:

        通过信号量实现同步操作;由信号量来决定线程是继续运行还是阻塞等待

        信号量代表某一类资源,其值表示系统中该资源的数量

        信号量是一个受保护的变量,只能通过三种操作来访问:初始化、P操作(申请资源)、V操作(释放资源)

        信号量的值为非负整数

3)函数接口

int sem_init(sem_t *sem, int pshared, unsigned int value)

功能:初始化信号量

参数: sem:初始化的信号量对象

            pshared:信号量共享的范围(0: 线程间使用 非0:1进程间使用)

            value:信号量初值

返回值:成功 0

              失败 -1

int sem_wait(sem_t *sem)

功能:申请资源 P操作

参数:sem:信号量对象

返回值:成功 0

              失败 -1

        注:此函数执行过程,先对信号量进行减1,当信号量的值大于等于0时,表示有资源可以用,则继续执行;当信号量的值小于0时,表示没有资源可以使用,函数阻塞

int sem_post(sem_t *sem)

功能:释放资源 V操作

参数:sem:信号量对象

返回值:成功 0

              失败 -1

        注:释放一次信号量的值加1,函数不阻塞

练习:通过线程实现数据的输入输出,主线程循环从终端输入,线程函数将数据循环输出。

        两个线程谁先执行是不知道的,如果先执行子进程执行函数sem_wait(p操作 消费着)因为初始化的时候资源为零 那么p操作减一就小于零了那么子进程就会阻塞在这个地方,然后看主函数scanf用户没有输入的话也是在阻塞。所以这两个线程都在阻塞,如果用户输入的话就会继续执行函数sem_post(v操作 生产者)资源加一 ,v操作加一后 p操作就会对该资源进行消费然后减一。

看红色

如果你一次输入的字符超过32个的话

先看红色的情况:

理想情况下fgets先读31个然后去执行函数sem_post(v操作生产者)然后子进程执行函数sem_wait(p操作消费者)然后打印完之后再去把主线程缓存区里面的读到buf中 然后v操作加一 再然后p操作减一

不理想情况下当v操作(生产者)释放资源后 p操作(消费者)没有申请资源 那么fgets会从缓存区中把剩下的读到buf中 就把buf以前的值给覆盖了 v操作(生产者)加一 那么子进程要申请资源的话就会打印两次一样的东西。

红蓝结合就是防止那种不理想的情况严格保证读一次打印一次

先执行那个进程也是不知道的,如果是子进程那么执行sem_wait(&sem)会进行阻塞,就会执行主进程执行sem_wait(&sem1)因为一开始有资源就是继续执行fgets然后读32个后执行v操作(生产者)加一 如果这是子进程的p操作(消费者)没有及时申请资源 那么在执行主函数时执行sem_wait(&sem1)因为信号为零那么就会一直阻塞 所以子进程的p操作一定会执行 然后进行打印 然后执行sem_post(&sem1)v操作进行加一再执行主进程里的sem_wait(&sem1) 然后依次循环。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值