线程同步

互斥锁(互斥量)

创建互斥锁

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
原文地址:https://www.cnblogs.com/xumaomao/p/13110990.html