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

发布时间 2023-05-06 12:00:39作者: WTSRUVF

# 互斥锁

/*
    #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;
}