Linux线程间通信学习记录(线程同步)

0.线程间通信的方法

(1).全局变量(要结合同步机制)

(2).信号量

(3).P操作

(4).V操作

一.线程同步

        同步:指的是多个任务按照约定的先后次序相互配合完成一件事情

        由信号量来决定线程是继续运行还是阻塞等待

二.信号量

①.特点:

                (1).信号量代表某一类资源,其值代表系统中该资源的数量。

                (2).信号量是一个受保护的变量,只能通过3种操作来访问

                        初始化

                        P操作(申请资源,线程要访问资源的时候用)

                        V操作 (释放资源,此线程对某变量的操作完成了,把这个变量的使用权交给其他                                        线程)

②.类型

        (1).无名信号量(基于内存的信号量,主要用于线程之间的同步)

        (2).有名信号量

三.信号量相关C函数

1.信号量初始化 - sem_init

        功能:     

                对信号量进行初始化

                成功时返回(0),失败时返回(EOF),并且会置errno

        参数

                sem        :指向要初始化的信号量对象

                pshared  :       

                                0:代表信号量在线程间使用

                                1:代表信号量在进程间使用

                value      :信号量的初始值

                                大于0:表示有资源

                                等于0:表示没有资源

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

2.P操作 - sem_wait   (申请操作资源)

        功能

                可能会阻塞任务(等待有资源可使用)

                申请操作资源,在任务需要访问某个资源前,要对代表这个资源的信号量进行P操作               ,检查当前有没有资源,没有则阻塞等待资源;当此任务访问完资源了/有新的资源可用,则           执行V操作。

                成功时返回(0),失败时返回(EOF)

        参数

                sem:指向要操作的信号量对象

int sem_wait(sem_t *sem);
if(信号量的值 > 0)
{
    申请资源的任务继续运行;
    信号量的值--;
}
else
{
    申请资源的任务阻塞;
}

3.V操作 - sem_post(释放了资源/有新的资源可用)

        功能

                成功时返回(0),失败时返回(EOF)

        参数

                sem:指向要操作的信号量对象

int sem_post(sem_t *sem);
信号量的值++;
if(有任务在等待资源)
{
    唤醒等待的任务,让其继续运行;
}

四.线程同步代码实现(利用信号量)

#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>


char buf[32] = {0};
void *thread_func(void *arg);
sem_t sem_w;        //代表有没有可写的缓冲区
sem_t sem_r;        //代表有没有可读的缓冲区

int main()
{
    pthread_t a_thread;

    /* 1.信号量初始化 */
    if(0 > sem_init(&sem_r,0,0))    //初始化不可读
    {
        perror("sem_init sem_r error");
        exit(-1);
    }
    if(0 > sem_init(&sem_w,0,1))    //初始化为可写
    {
        perror("sem_init sem_w error");
        exit(-1);
    }

    /* 2.创建子线程 */
    if(0 != pthread_create(&a_thread,NULL,thread_func,NULL))
    {
        printf("fail to create thread_func\n");
        exit(-1);
    }

    do
    {
        /* 3.阻塞等待,直到可以进行写操作 */
        sem_wait(&sem_w);
        fgets(buf,32,stdin);
        /* 4.填充好数据后,进行V操作,使其他线程可对该资源进行读操作 */
        sem_post(&sem_r);
    } while (strncmp(buf,"quit",4) !=0 );       //没有输入quit就一直循环
    

   return 0;
}


/* 线程函数 */
void *thread_func(void *arg)
{
    while(1)
    {
        /* 1.每次要操作buf资源前,先进行P操作,阻塞等待有资源可读 */
        sem_wait(&sem_r);
        printf("you enter %ld characters\n",strlen(buf));

        /* 2.读完后,进行V操作,使其他线程可以对该资源进行写操作 */
        sem_post(&sem_w);
    }
}

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值