首页 > 其他分享 >互斥锁 读写锁 条件变量 生产者消费者问题

互斥锁 读写锁 条件变量 生产者消费者问题

时间:2023-05-06 12:00:10浏览次数:40  
标签:rwlock 生产者 读写 互斥 int cond pthread mutex NULL

# 互斥锁

/*
    #include <pthread.h>
        int pthread_mutex_init(pthread_mutex_t *restrict mutex,
        const pthread_mutexattr_t *restrict attr);   
            功能:初始化一个互斥变量mutex
            参数:
                mutex:需要初始化的互斥变量
                attr:属性,可以置NULL
                restrict修饰符:被修饰的指针不能被另一个指针操作

        int pthread_mutex_destroy(pthread_mutex_t *mutex);
            释放互斥变量
            
        int pthread_mutex_lock(pthread_mutex_t *mutex);
            加锁,阻塞函数

        int pthread_mutex_trylock(pthread_mutex_t *mutex);
            尝试加锁,加锁失败立即返回,不阻塞
        int pthread_mutex_unlock(pthread_mutex_t *mutex);
            解锁

*/

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>


int j;

pthread_mutex_t mutex;



void *callback(void* arg)
{


    int id = *(int *)arg;
    while(j < 1000)
    {
        pthread_mutex_lock(&mutex);
        if(j >= 1000)
        {
            pthread_mutex_unlock(&mutex);
            break;
        }
        // sleep(1);
        printf("%d sell the %d'th ticket\n", id, ++j);
        pthread_mutex_unlock(&mutex);
    }
    
    
    return NULL;
}


int main()
{
    j = 0;
    pthread_mutex_init(&mutex, NULL);
    pthread_t thread[3];
    int id0 = 0, id1 = 1, id2 = 2;
    pthread_create(&thread[0], NULL, callback, (void *)&id0);
    pthread_create(&thread[1], NULL, callback, (void *)&id1);
    pthread_create(&thread[2], NULL, callback, (void *)&id2);

    // pthread_detach(thread[0]);
    // pthread_detach(thread[1]);
    // pthread_detach(thread[2]);
    pthread_join(thread[0], NULL); // pthread_join是阻塞函数
    pthread_join(thread[1], NULL);
    pthread_join(thread[2], NULL);
    pthread_mutex_destroy(&mutex);
    printf("tickets sell out!!!\n");

    pthread_exit(NULL);


    // sleep(60);



    return 0;
}

 

 

# 读写锁

 

/*
        #include <pthread.h>
        int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
            const pthread_rwlockattr_t *restrict attr);

        int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
        int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
        int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
        int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
        int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
        int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);


*/

 

 

 

 

# 条件变量   生产者消费者问题

 

/*
    pthread_cond_xxx



        #include <pthread.h>

        int pthread_cond_init(pthread_cond_t *restrict cond,
            const pthread_condattr_t *restrict attr);

        int pthread_cond_destroy(pthread_cond_t *cond);


        int pthread_cond_broadcast(pthread_cond_t *cond); // 激活所有wait线程
        int pthread_cond_signal(pthread_cond_t *cond); // 激活至少一个

        int pthread_cond_wait(pthread_cond_t *restrict cond,  
            pthread_mutex_t *restrict mutex);
            // 阻塞等待,但会先对第二个参数mutex解锁,当解除阻塞时,会再次加锁

        int pthread_cond_timedwait(pthread_cond_t *restrict cond,
        pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);


*/

// 生产者消费者问题


#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

pthread_mutex_t mutex;
pthread_cond_t cond;


struct Node
{
    int num;
    struct Node* next;
}

struct Node *head = NULL;

void *producer(void *arg)
{   

    while(1)
    {
        pthread_mutex_lock(&mutex);
        struct Node* node = (struct Node*) malloc(siezeof(struct Node));
        node->num = rand() % 1000;
        node->next = head;
        head = node;
        printf("add node, num: %d, tid: %d\n", node->num, pthread_self());
        usleep(100);
        pthread_cond_signal(*cond);
        pthread_mutex_unlock(&mutex);


    }
    return NULL;
}

void *customer(void *arg)
{
    while(1)
    {
        pthread_mutex_lock(&mutex);
        if(head != NULL)
        {
            struct Node* node = head;
            head = head->next;

            printf("delete node, num: %d, tid: %d\n", node->num, pthread_self());
            free(node);
            usleep(100);
            pthread_mutex_unlock(&mutex);
        }
        else
        {
            pthread_cond_wait(&cond, &mutex);
            pthread_mutex_unlock(&mutex);

        }
    }
    return NULL;
}






int main()
{

    pthread_mutex_init(&mutex);
    pthread_cond_init(&cond);

    phtread_t ptids[5], ctids[5];

    for(int i = 0; i < 5; i++)
    {
        pthread_create(&ptids[i], NULL, producer, NULL);
        pthread_create(&ctids[i], NULL, customer, NULL);
    }


    for(int i = 0; i < 5; i++)
    {
        pthread_detach(ptids[i]);  // pthread_join是阻塞的,所以多个线程最好用detach
        pthread_detach(ctids[i]);
    }


    while(1)
    {
        sleep(10);
    }


    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);




    pthread_exit(NULL);






    return 0;
}

 

标签:rwlock,生产者,读写,互斥,int,cond,pthread,mutex,NULL
From: https://www.cnblogs.com/WTSRUVF/p/17376838.html

相关文章

  • delphi 互斥量,只允许运行一个实例
    效果图: 代码超简单的:procedureTFrmLogin.FormCreate(Sender:TObject);varFmutex:THandle;begin//创建一个命名的互斥量,确保同一时间只有一个实例在运行//第三个参数是自定义的,随便取的,但一定要是唯一的标识FMutex:=CreateMutex(nil,True,'MyDelphiAppMutex')......
  • Rabbitmq 介绍 、安装、基于Queue实现生产者消费者模型、基本使用、消息安全之ack、du
    师承老刘llnb一、消息队列介绍1.1介绍消息队列就是基础数据结构中的“先进先出”的一种数据机构。想一下,生活中买东西,需要排队,先排的人先买消费,就是典型的“先进先出”1.2MQ解决什么问题MQ是一直存在,不过随着微服务架构的流行,成了解决微服务之间问题的常用工具。应用解耦......
  • Sharding-JDBC:实现数据库的读写分离?
    简介轻量级Java框架,在Java的JDBC层提供额外服务,以jar包的形式提供服务(增强版数据库连接驱动)。适用于基于JDBC的ORM框架、支持第三方数据库连接池、支持实现了JDBC规范的数据库。 读写分离:基于已配置好主从复制的多个数据库。 使用步骤在springboot项目中使用。一、......
  • Python教程:pandas读写txt文件——DataFrame和Series
    大家用pandas一般都是读写csv文件或者tsv文件,读写txt文件时一般就withopen了,其实pandas数据类型操作起来更加方便,还是建议全用pandas这一套。读txt文件代码如下,主要是设置正则表达式的分隔符(sep参数),和列名取消(header参数),以及不需要列索引(index_col)。1df=pd.read_csv("workl......
  • 从源码深入理解读写锁(golang-RWMutex)
    环境:go1.19.8在读多写少的情况下,即使一段时间内没有写操作,大量并发的读访问也不得不在Mutex的保护下变成串行访问,这种情况下,使用Mutex,对性能影响比较大。所以就要区分读写操作。如果某个读操作的g持有了锁,其他读操作的g就不必等待了,可以并发的访问共享变量,这样就可以将串行的......
  • 使用 Sharding Jdbc 实现读写分离
    上一篇博客介绍了MySQL的主从复制的搭建,为实现读写分离创造了条件。对于一个网站来说,80%来源于读操作,绝大多数情况下的网站宕机,都是由于过多的读操作导致的,因此在实际的生产环境中,经常会搭建一主多从的架构,主库只负责写操作,多个从库用来负责读操作,对于少量需要实时获取信息的读......
  • C++文件读写常用操作整理
    C++对于文件的操作需要包含<fstream>头文件文件类型分为两种:文本文件-文件以文件的ASCII码的形式存储在计算机中二进制文件-文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们操作文件的三大类:ofstream:写操作ifstream:读操作fstream:读写操作一、文......
  • 22 同步与互斥(八)总结
    1实现的基础同步与互斥的基本操作:spinlock;semaphore;mutex而实现上述操作的基本是基于:原子操作;中断屏蔽;抢占屏蔽来实现的对于spinlock;semaphore;mutex等相关的操作,基本实现都是lock时,放回成功表示上锁成功。否则就需要等待对应unlock后才能返回成功,进入临界区2彼此的关联与区......
  • 21 同步与互斥(七)互斥量
    1简介mutex相对于semaphore更加高效。mutex在面对SMP时,如果mutex在别的CPU上运行,而“我”是唯一在等待这个mutex的进程。此时“我”是不会去休眠的,而是原地spin2mutex的结构和API2.1mutex结构structmutexmy_mutex;structmutex{ /*1:unlocked,0:locked,negativ......
  • 在Android中实现文件读写
    android实现下载文件/***从网上下载*@paramurl下载路径*@paramoutputFile创建本地保存流的文件*@return*@return下载失败返回1(比如没有网络等情况)下载成功返回0*/publicstaticintdownloadFile(Stri......