• 线程同步


    互斥锁(互斥量)

    创建互斥锁

    pthread_mutex_t mutex;

    初始化互斥锁

    pthread_mutex_init(pthread_mutex_t* mutex,
      const pthread_mutexattr_t* attr
    );

    销毁互斥锁

    pthread_mutex_unlock(pthread_mutex_t *mutex);

    加锁

    //如果加锁的时候发现锁已经被锁上了,线程会一直阻塞在这个位置
    pthread_mutex_lock(pthread_mutex_t *mutex);

    //尝试加锁,失败返回,不阻塞
    pthread_mutex_trylock(pthread_mutex_t *mutex);

    解锁

    pthread_mutex_unlock(pthread_mutex_t *mutex);

    实例

    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <string.h>
    #include <pthread.h>
    
    #define MAX 10000
    
    int number;
    
    //创建一把互斥锁
    pthread_mutex_t mutex;
    
    void* funcA_num(void* arg)
    {
            int i;
            for(i=0; i<MAX; i++)
            {
                    //加锁
                    pthread_mutex_lock(&mutex);
                    int cur = number;
                    cur++;
                    number = cur;
                    printf("Thread A, id = %lu, number = %d
    ", pthread_self(), number);
                    //解锁
                    pthread_mutex_unlock(&mutex);
                    usleep(10);
            }
    
            return NULL;
    }
    
    void* funcB_num(void* arg)
    {
            int i;
            for(i=0; i<MAX; i++)
            {
                    //加锁
                    pthread_mutex_lock(&mutex);
                    int cur = number;
                    cur++;
                    number = cur;
                    printf("Thread B, id = %lu, number = %d
    ", 
    pthread_self(), number);
                    //解锁
                    pthread_mutex_unlock(&mutex);
                    usleep(10);
            }
    
            return NULL;
    }
    
    int main(int argc, const char* argv[])
    {
            pthread_t p1, p2;
    
            //初始化互斥锁
            pthread_mutex_init(&mutex, NULL);
    
            //创建两个子进程
            pthread_create(&p1, NULL, funcA_num, NULL);
            pthread_create(&p2, NULL, funcB_num, NULL);
    
            //阻塞,回收资源
            pthread_join(p1, NULL);
            pthread_join(p2, NULL);
    
            //释放互斥锁资源
            pthread_mutex_destroy(&mutex);
    
            return 0;
    }
    View Code

    条件变量

    创建条件变量

    pthread_cond_t cond;

    初始化一个条件变量

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

    销毁一个条件变量

    pthread_cond_destroy(pthread_cond_t *cond);

    阻塞等待一个条件变量

    pthread_cond_wait(
        pthread_cond_t *restrict cond,
        pthread_mutex_t *restrict mutex
    );
    • 阻塞线程并将已经上锁的mutex解锁

    • 在解除阻塞时会对互斥锁加锁

    限时等待一个条件变量

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

    唤醒至少一个阻塞在条件变量上的线程

    pthread_cond_signal(pthread_cond_t *cond);

    唤醒全部阻塞在条件变量上的线程

    pthread_cond_broadcast(pthread_cond_t *cond);

    使用互斥锁加条件变量实现生成者消费者模型

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdlib.h>
    
    typedef struct node
    {
            int data;
            struct node* next;
    }Node;
    
    Node* head = NULL;
    
    pthread_mutex_t mutex;
    
    pthread_cond_t cond;
    
    void* producer(void* arg)
    {
            while(1)
            {
            Node* pnew = (Node*)malloc(sizeof(Node));
            pnew->data = rand() % 1000;
    
            pthread_mutex_lock(&mutex);
            pnew->next = head;
            head = pnew;
            printf("produce: %lu, %d
    ", pthread_self(), pnew->data);
            pthread_mutex_unlock(&mutex);
            pthread_cond_signal(&cond);
            sleep(rand() % 3);
            }
    
            return NULL;
    }
    
    void* customer(void* arg)
    {
            while(1)
            {
                    pthread_mutex_lock(&mutex);
                    if(head == NULL)
                    {
                            pthread_cond_wait(&cond, &mutex);
                    }
                    Node* pdel = head;
                    head = head->next;
                    printf("customer: %lu, %d
    ", pthread_self(), pdel->data);
                    free(pdel);
                    pthread_mutex_unlock(&mutex);
            }
    
            return NULL;
    }
    
    int main(int argc, const char* argv[])
    {
            pthread_t p1, p2;
    
            pthread_mutex_init(&mutex, NULL);
    
            pthread_cond_init(&cond, NULL);
    
            pthread_create(&p1, NULL, producer, NULL);
            pthread_create(&p2, NULL, customer, NULL);
    
            pthread_join(p1, NULL);
            pthread_join(p2, NULL);
    
            pthread_mutex_destroy(&mutex);
            pthread_cond_destroy(&cond);
    
            return 0;
    }
    View Code

    信号量(高级互斥锁)

    创建信号量

    sem_t sem;

    初始化信号量

    sem_init(sem_t* sem, int pshared, unsigned int value);

    pshared:

    • 0:线程同步
    • 1:进程同步

    value:最多有几个线程操作共享资源

    销毁信号量

    sem_destroy(sem_t *sem);

    加锁

    sem_wait(sem_t *sem);

    调用一次相当于sem值减一,如果sem值为0线程会阻塞

    解锁

    sem_post(sem_t *sem);

    调用一次相当于sem值加一

    尝试加锁

    sem_trywait(sem_t *sem);

    限时尝试加锁

    sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

    使用信号量实现生成者消费者模型

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <semaphore.h>
    
    sem_t produce_sem;
    sem_t custom_sem;
    
    typedef struct node
    {
            int data;
            struct node* next;
    }Node;
    
    Node *head = NULL;
    
    void* producer(void * arg)
    {
            while(1)
            {
                    sem_wait(&produce_sem);
                    Node *pnew = (Node*)malloc(sizeof(Node));
                    pnew->data = rand()%1000;
                    pnew->next = head;
                    head = pnew;
                    printf("producer: %lu, %d
    ", pthread_self(), pnew->data);
                    sem_post(&custom_sem);
                    sleep(rand()%5);
            }
    
            return NULL;
    }
    
    void* customer(void* arg)
    {
            while(1)
            {
                    sem_wait(&custom_sem);
                    Node* pdel = head;
                    if(head == NULL)
                    {
                            exit(1);
                    }
                    head = head->next;
                    printf("customer: %lu, %d
    ", pthread_self(), pdel->data);
                    free(pdel);
                    sem_post(&produce_sem);
    
                    sleep(rand()%5);
            }
    
            return NULL;
    }
    
    int main(int argc, const char* argv[])
    {
            pthread_t thid[2];
    
            sem_init(&produce_sem, 0, 4);
            sem_init(&custom_sem, 0, 0);
    
            pthread_create(&thid[0], NULL, producer, NULL);
            pthread_create(&thid[1], NULL, customer, NULL);
    
            int i;
            for(i=0; i<2; i++)
            {
                    pthread_join(thid[i], NULL);
            }
    
            sem_destroy(&produce_sem);
            sem_destroy(&custom_sem);
    
            return 0;
    }
    View Code
  • 相关阅读:
    uva 1584.Circular Sequence
    成为Java顶尖程序员 ,看这11本书就够了
    java 线程同步 原理 sleep和wait区别
    xargs -r
    java
    事故分析
    各大互联网公司架构演进之路汇总
    char 汉字
    nginx优化之request_time 和upstream_response_time差别
    学习进度05
  • 原文地址:https://www.cnblogs.com/xumaomao/p/13110990.html
Copyright © 2020-2023  润新知