线程的同步与互斥

2023-12-24 22:44:32

抢票的例子

竞争过程

进程A被切走

进程B被切走

结论:

互斥

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
  • mutex: 指向要初始化的互斥锁的指针。
  • attr: 用于设置互斥锁属性的指针,通常可以传入 NULL 以使用默认属性。

锁的本质

加锁

解锁

线程安全与重入

死锁

线程同步

生产消费模型

例子

条件变量

demo

#include<iostream>
#include<string>
#include<pthread.h>
#include<unistd.h>

int tickets=1000;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void *start_routine(void* args){
    std::string name=static_cast<const char*>(args);
    while(true){
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond,&mutex);
        std::cout<<name<<"->"<<tickets<<std::endl;
        tickets--;
        pthread_mutex_unlock(&mutex);
    }
    return nullptr;
}

int main(){
    const int num=5;
    pthread_t tid[num]{};
    for(int i=0;i<num;i++){
        char *name=new char[64];
        snprintf(name,sizeof(name),"thread %d",i+1);
        pthread_create(tid+i,nullptr,start_routine,name);
    }
  
    while(true){
        std::cout<<"main thread weak up"<<std::endl;
        pthread_cond_signal(&cond);
        sleep(1);
    }

    for(int i=0;i<num;i++){
        pthread_join(tid[i],nullptr);
    }


    return 0;


}

信号量

常用函数

环形队列

环形队列代码

#include"RingQueue.hpp"
#include<unistd.h>
#include<pthread.h>
#include<random>
#include<iostream>

void *ProductorRoutine(void* rq){
    RingQueue<int> *ringqueue=static_cast<RingQueue<int>*>(rq);
    while(true){
        int data=rand()%10+1;
        ringqueue->Push(data);
        std::cout<<"生产完成 生产的数据是:"<<data<<std::endl;
        sleep(1);
    }
}

void *ConsumerRoutine(void *rq){
    RingQueue<int> *ringqueue=static_cast<RingQueue<int>*>(rq);
    while(true){
        int data;
        ringqueue->Pop(data);
        std::cout<<"消费完成 消费数据是:"<<data<<std::endl;
        sleep(1);
    }
}



int main(){
    
    srand((unsigned int)time(nullptr)^getpid()^pthread_self());
    RingQueue<int> *rq=new RingQueue<int>();
    pthread_t p,c;

    pthread_create(&p,nullptr,ProductorRoutine,rq);
    pthread_create(&c,nullptr,ConsumerRoutine,rq);

    pthread_join(p,nullptr);
    pthread_join(c,nullptr);

}
#include<semaphore.h>
#include<vector>
#include<cassert>
#include<ctime>
#include<sys/types.h>

static const int gcap=5;

template<class T>
class RingQueue{
public:
    void P(sem_t &sem){
        int n=sem_wait(&sem);
        assert(n==0);
        (void)n;
    }

    void V(sem_t &sem){
        int n=sem_post(&sem);
        assert(n==0);
        (void)n;
    }

public:
    RingQueue(const int &cap=gcap):_q(cap),_cap(cap){
        int n=sem_init(&_spaceSem,0,_cap);
        assert(n==0);
        n=sem_init(&_dataSem,0,0);
        assert(n==0);

        productorStep=ConsumerStep=0;
    }

    void Push(const T &in){
        P(_spaceSem);
        _q[productorStep++]=in;
        productorStep%=_cap;
        V(_dataSem);
    }

    void Pop(T &out){
        P(_dataSem);
        out=_q[ConsumerStep++];
        ConsumerStep%=_cap;
        V(_spaceSem);
    }

    ~RingQueue(){
        sem_destroy(&_spaceSem);
        sem_destroy(&_dataSem);
    }
    private:
    std::vector<T> _q;
    int _cap;
    sem_t _spaceSem;  //生产者 空间资源
    sem_t _dataSem;   //消费者 数据资源
    int productorStep;
    int ConsumerStep;
};

文章来源:https://blog.csdn.net/b1169909203/article/details/135096559
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。