Linux程序设计之信号量

1.信号量,可拿停车和停车位来简单理解。首先,比如创建了一个大小为8的信号量psem(停车位),只有当信号量psem大于0时(有停车位),才可以访问资源(停车。同时,可以将将停车位上的车开出,增加停车为资源。比如8个停车位,占了5个,只剩下3个。此时,可清空一个停车位,让剩余的停车位数量变成4。

2.代码:

/*利用生产者和消费者模型,理解信号量*/

#include 
#include 
#include 
#include 
#include 

//创建一个互斥量
pthread_mutex_t mutex;

//创建两个信号量
sem_t psem,csem;

struct Node{
    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;
        newNode->num = rand() % 1000;
        head = newNode;
        printf("add node,num : %d,tid : %ld\n",newNode->num,pthread_self());

        pthread_mutex_unlock(&mutex);

        sem_post(&csem);    //生产之后,增加信号csem的数量,让消费者可以消费
    }
    return NULL;
}

void * customer(void * arg)
{
    while(1)
    {
        sem_wait(&csem);    //利用信号量判断是否可继续执行
        pthread_mutex_lock(&mutex);
        //保存头节点
        struct Node *temp = head;
        head = head->next;  //删除节点
        printf("del node,num : %d,tid : %ld\n",temp->num,pthread_self());
        free(temp);
        //条件变量进行阻塞等待,直到收到可继续执行的条件变量。
        pthread_mutex_unlock(&mutex);

        sem_post(&psem);    //增加生产者的信号量,告诉生产者可以继续生产,相当于给生产者空出一个可存放物品的位置
    }
    return NULL;
}

int main()
{
    //初始化互斥量
    pthread_mutex_init(&mutex,NULL);

    //初始化信号量
    sem_init(&psem,0,8);
    sem_init(&csem,0,0);

    //创建5个消费者和消费者线程
    pthread_t ptid[5],ctid[5];
    for(int i = 0;i < 5;i++)
    {
        pthread_create(&ptid[i],NULL,producer,NULL);
        pthread_create(&ctid[i],NULL,customer,NULL);
    }

    //设置线程分离,方便线程在结束后,自动回收其资源
    for(int i = 0;i < 5;i ++)
    {
        pthread_detach(ptid[i]);
        pthread_detach(ctid[i]);
    }

    //阻塞进程
    while(1)
    {
        sleep(100);
    }

    //销毁互斥量
    pthread_mutex_destroy(&mutex);

    //销毁信号量
    sem_destroy(&psem);
    sem_destroy(&csem);

    //退出主线程,不会影响子线程
    pthread_exit(NULL);

    return 0;
}

3.运行结果:

Linux程序设计之信号量_第1张图片

4.总结:信号量相当于为动物园创建了一定数量的入口,没有一个线程访问时,动物园的入口数量就减少一个,当一个线程结束访问时,动物园的入口数量就恢复一个。只有当动物园的入口数量大于0时,其他线程才可以访问动物园,即访问资源,负责,处于阻塞等待状态。

你可能感兴趣的:(Linux程序设计,linux,运维,多线程,信号量)