(八)Linux系统编程之线程(下)

一、信号量(信号灯)

(高级的互斥锁)
mutex=1
lock() mutex=0
unlock() mutex=1
mutex实现的同步都是串行的

互斥锁:串行
信号量:并行


1、头文件 - semaphore.h


2、信号量类型

  • sem_t sem;
  • 加强版的互斥锁【mutex>=1】

3、主要函数

  • 初始化信号量
sem_init(sem_t *sem,int pshared,unsigned int value);

0 - 线程同步
1 - 进程同步
value - 最多有几个线程操作共享数据

  • 销毁信号量
sem_destroy(sem_t *sem);
  • 加锁
 sem_wait(sem_t *sem);

调用一次相当于对sem做了–(减减)操作
如果sem值为0,线程会阻塞

  • 尝试加锁
sem_trywait(sem_t *sem);

sem==0,加锁失败,不阻塞,直接返回

  • 限时尝试加锁
sem_timedwait(sem_t *sem,xxxxx);
  • 解锁 ++
sem_post(sem_t *sem);

对sem做了++(加加 )操作


4、练习
使用信号量实现生产者、消费者模型

sem_t produce_sem;
sem_t custom_sem;

//节点结构
typedef struct node
{
        int data;
        struct node* next;
}Node;

//永远指向链表头部指针
Node* head=NULL;

//生产者
void* producer(void* arg)
{
        while(1){
                sem_wait(&produce_sem);   //produce_sem -- ==0,阻塞
                //创建一个链表的节点
                Node* pnew=(Node*)malloc(sizeof(Node));
                //节点初始化
                pnew->data=rand()%1000;//0-999
                //指针域
                pnew->next=head;
                head=pnew;
                printf("++++++ 生产者:%lu,%d\n",pthread_self(),pnew->data);

                sem_post(&custom_sem); //custom_sem++

                sleep(rand()%5);
        }
        return NULL;
}
//消费者
void* customer(void* arg)
{
        while(1){
                sem_wait(&custom_sem);
                //链表不为空,删除一个节点,删除头结点
                Node* pdel=head;
                head=head->next;
                printf("------ 消费者:%lu,%d\n",pthread_self(),pdel->data);
                free(pdel);
                sem_post(&produce_sem);
                sleep(rand()%5);
        }
        return NULL;
}

int main(int argc,const char* argv[])
{
        pthread_t thid[2];

        //init
        sem_init(&produce_sem,0,4);
        sem_init(&custom_sem,0,0);

        //创建生产者线程
        pthread_create(&thid[0],NULL,producer,NULL);
        //创建消费者线程
        pthread_create(&thid[1],NULL,customer,NULL);

        //阻塞回收子线程
        for(int i=0;i<2;++i){
                pthread_join(thid[i],NULL);
        }

        sem_destroy(&produce_sem);
        sem_destroy(&custom_sem);

        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值