> ## Content Index
> Fetch the complete content index at: https://blog.hacking.pub/llms.txt
> Use this file to discover other available public pages before exploring further.

# 关于锁的总结（一）互斥量
- URL: https://blog.hacking.pub/2018/05/23/mutex/
- Published: 2018-05-23T09:19:59.000Z
- Updated: 2018-05-23T09:21:31.000Z
- Author: chainhelen
- Tags: 互斥量, 锁, mutex, 临界区, 临界资源, critical resource, pthread, linux, race

#### 锁

我们语境下的`锁`是一种同步机制，用于计算机在多任务环境下访问公共资源达到互斥作用。

**临界资源**  
`临界资源`（`Critical Resource`）是一次仅允许一个进程（任务）使用的共享资源  
**临界区**  
每个进程（任务）中访问临界资源的代码块。每次只允许一个进程进入`临界区`（`Critical Section`）

###### 互斥量

`互斥量`（`mutex`），用于保护临界区的。下面举个例子，三个`task`，其中两个`生产者`，一个`消费者`  
以下代码有如下假定：

1. 生产者在`shared.buf[i]`生成出数据 `i`
2. 生产者竞争（`race`）生产，直到所有`buf`区域都有数据，并此时停止生成
3. 消费者在整个`buf`全有数据后才开始消费

```
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define MAXBUFLEN 30000
#define PRODUCERNUM 2

struct Shared {
    pthread_mutex_t mutex;
    int buf[MAXBUFLEN];
    int sum;
} shared = {
    PTHREAD_MUTEX_INITIALIZER, // init the mutex
    {0},
    0
};

void *produce(void *arg) {
    for( ; ; ) {
        pthread_mutex_lock(&shared.mutex);
        if (shared.sum >= MAXBUFLEN) {
            pthread_mutex_unlock(&shared.mutex);
            return(NULL);
        }
        shared.buf[shared.sum] = shared.sum; // produce data 1 in shared.buf[shared.sum]
        shared.sum++;
        pthread_mutex_unlock(&shared.mutex);
        *((int *)arg) += 1;
        sleep(0);
    }
}

void *comsume(void *arg) {
    (void) arg;
    for (int i = 0;i < MAXBUFLEN;i++) {
        if (i != shared.buf[i]) {
            printf("buf[%d] = %d\n", i, shared.buf[i]);
        }
    }
    return (NULL);
}

int main() {
    pthread_t tid_produce[PRODUCERNUM], tid_consume;
    int count[PRODUCERNUM];

    for (int i = 0;i < PRODUCERNUM;i++) {
        count[i] = 0;
        pthread_create(&tid_produce[i], NULL, produce, &count[i]);
    }

    for (int i = 0;i < PRODUCERNUM;i++) {
        pthread_join(tid_produce[i], NULL);
        printf("producer%d produce count %d buffer\n", i, count[i]);
    }

    pthread_create(&tid_consume, NULL, comsume, NULL);
    pthread_join(tid_consume, NULL);

    getchar();
    return 0;
}

producer0 produce count 14997 buffer
producer1 produce count 15003 buffer

```