Linux生产者和消费者模型 条件变量 信号量

/*
    条件变量类型 pthread_cond_t
    int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    int pthread_cond_destory(pthread_cond_t * cond);
    int pthread_cond_wait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict mutex);
        阻塞函数,调用了该函数,线程阻塞
    int pthread_cond_timewait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
        等待多长时间,调用了该函数,线程阻塞直至时间结束
    int pthread_cond_signal(pthread_cond_t * cond);
        唤醒至少一个等待的线程
    int pthread_cond_broadcast(pthread_cond_t * cond);
        唤醒所有等待的线程
*/


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

pthread_mutex_t mutex;

pthread_cond_t cond;
struct Node
{
    /* data */
    int num;
    struct Node *next;
};

struct Node * head = NULL;


void * producer(void * arg) {
    while(1) {
        pthread_mutex_lock(&mutex);
        struct Node * newnode = (struct Node*) malloc(sizeof(struct Node));
        newnode->next = head;
        head = newnode;
        newnode->num = rand() % 1000;
        printf("add node, node num :%d, tid, %ld\n", newnode->num, pthread_self());
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
        usleep(100);
    }
    return NULL;
}

void * customer(void * arg) {
    while(1) {
        pthread_mutex_lock(&mutex);
        struct Node *temp = head;
        if(head != NULL) {
            head = head->next;
            printf("delete node,num:%d, tid:%ld\n", temp->num, pthread_self());
            free(temp);
            pthread_mutex_unlock(&mutex);
            usleep(100);
        } else {
            pthread_cond_wait(&cond, &mutex);
            pthread_mutex_unlock(&mutex);
        }
        
    }
    return NULL;
}

int main() {
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_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_detach(ctids[i]);
    }

    while(1) {
        sleep(10);
    }

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

    pthread_exit(NULL);

    return 0;
}

/*
    #include <semaphore.h>
    函数量类型:sem_t
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    参数:
        -sem 需要初始化的信号量的地址
        -pshared 表示用在进程还是线程之间 0 线程  非0 进程
        -value:记录信号量中的值

    int sem_destory(sem_t *sem);
        释放资源
    int sem_wait(sem_t *sem);
        对信号量的值减一,如果值为零,就阻塞
    int sem_trywait(sem_t *sem);
    int sem_timewait(sem_t *sem, const struct timespec *abs_timeout);
        等待多久的时间
    int sem_post(sem_t *sem);
        信号量的值加一
    int sem_getvalue(sem_t *sem, int *sval);
*/



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

pthread_mutex_t mutex;
sem_t psem;
sem_t csem;

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

struct Node * head = NULL;


void * producer(void * arg) {
    while(1) {
        sem_wait(&psem);
        pthread_mutex_lock(&mutex);
        struct Node * newnode = (struct Node*) malloc(sizeof(struct Node));
        newnode->next = head;
        head = newnode;
        newnode->num = rand() % 1000;
        printf("add node, node num :%d, tid, %ld\n", newnode->num, pthread_self());
        pthread_mutex_unlock(&mutex);
        sem_post(&csem);
        usleep(100);
    }
    return NULL;
}

void * customer(void * arg) {
    while(1) {
        sem_wait(&csem);
        pthread_mutex_lock(&mutex);
        struct Node *temp = head;
        head = head->next;
        printf("delete node,num:%d, tid:%ld\n", temp->num, pthread_self());
        free(temp);
        pthread_mutex_unlock(&mutex);

        sem_post(&psem);
        usleep(100);
        
    }
    return NULL;
}

int main() {
    pthread_mutex_init(&mutex, NULL);
    sem_init(&psem, 0, 8);
    sem_init(&csem, 0, 0);

    pthread_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_detach(ctids[i]);
    }

    while(1) {
        sleep(10);
    }

    pthread_mutex_destroy(&mutex);

    pthread_exit(NULL);

    return 0;
}

可以把sem理解为车位,wait就占一个车位,pos就空一个车位,车位被占满就阻塞,直至有多余的空出来的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值