问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C语言如何实现互斥

创作时间:
作者:
@小白创作中心

C语言如何实现互斥

引用
1
来源
1.
https://docs.pingcode.com/baike/954530

互斥是多线程编程中的一个重要概念,用于保证多个线程在访问共享资源时的正确性和一致性。本文将详细介绍C语言中实现互斥的三种主要方法:互斥锁(mutex)、条件变量(condition variable)和原子操作(atomic operations),并通过具体的代码示例帮助读者理解这些概念。

一、互斥锁(mutex)

互斥锁是最常见的实现互斥的方式。在C语言中,互斥锁通常由pthread_mutex_t类型表示,并通过一系列函数进行操作。

1.1 互斥锁的初始化

在使用互斥锁之前,必须进行初始化。可以通过静态初始化或者动态初始化来完成。

静态初始化:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

动态初始化:

pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);

1.2 互斥锁的加锁和解锁

加锁和解锁操作分别使用pthread_mutex_lockpthread_mutex_unlock函数。

pthread_mutex_lock(&lock);
// 临界区代码
pthread_mutex_unlock(&lock);

1.3 使用互斥锁的示例

以下是一个简单的示例,展示了如何使用互斥锁保护共享数据:

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

pthread_mutex_t lock;
int shared_data = 0;

void* thread_function(void* arg) {
    pthread_mutex_lock(&lock);
    // 临界区开始
    shared_data++;
    printf("Shared Data: %d\n", shared_data);
    // 临界区结束
    pthread_mutex_unlock(&lock);
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    pthread_mutex_init(&lock, NULL);
    pthread_create(&thread1, NULL, thread_function, NULL);
    pthread_create(&thread2, NULL, thread_function, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_mutex_destroy(&lock);
    return 0;
}

二、条件变量(condition variable)

条件变量通常与互斥锁结合使用,用于线程间的同步。它允许线程在某些条件满足时被唤醒,从而实现更复杂的线程协调。

2.1 条件变量的初始化

条件变量的初始化与互斥锁类似,也可以通过静态初始化和动态初始化来完成。

静态初始化:

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

动态初始化:

pthread_cond_t cond;
pthread_cond_init(&cond, NULL);

2.2 条件变量的等待和通知

pthread_cond_wait函数用于等待条件变量,而pthread_cond_signalpthread_cond_broadcast函数用于通知等待的线程。

pthread_mutex_lock(&lock);
while (condition_not_met) {
    pthread_cond_wait(&cond, &lock);
}
// 条件满足后的操作
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond); // 唤醒一个等待的线程
pthread_cond_broadcast(&cond); // 唤醒所有等待的线程

2.3 使用条件变量的示例

以下是一个简单的示例,展示了如何使用条件变量进行线程同步:

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

pthread_mutex_t lock;
pthread_cond_t cond;
int ready = 0;

void* thread_function(void* arg) {
    pthread_mutex_lock(&lock);
    while (!ready) {
        pthread_cond_wait(&cond, &lock);
    }
    printf("Thread is running\n");
    pthread_mutex_unlock(&lock);
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_mutex_init(&lock, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_create(&thread, NULL, thread_function, NULL);
    // 主线程模拟一些工作
    sleep(1);
    pthread_mutex_lock(&lock);
    ready = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&lock);
    pthread_join(thread, NULL);
    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);
    return 0;
}

三、原子操作(atomic operations)

原子操作可以保证某些基本操作的不可分割性,从而避免数据竞争。C11标准提供了一些原子操作函数,如atomic_fetch_addatomic_fetch_sub等。

3.1 原子操作的使用

以下是一个简单的示例,展示了如何使用原子操作进行线程安全的计数器操作:

#include <stdatomic.h>
#include <pthread.h>
#include <stdio.h>

atomic_int counter = 0;

void* thread_function(void* arg) {
    for (int i = 0; i < 1000; ++i) {
        atomic_fetch_add(&counter, 1);
    }
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, thread_function, NULL);
    pthread_create(&thread2, NULL, thread_function, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    printf("Counter: %d\n", counter);
    return 0;
}

四、总结

C语言中实现互斥的方法主要包括互斥锁(mutex)、条件变量(condition variable)、原子操作(atomic operations)。其中,互斥锁是最常用的方法,通过加锁和解锁操作,可以保证临界区代码的线程安全。条件变量通常与互斥锁结合使用,用于线程间的同步。原子操作可以保证某些基本操作的不可分割性,从而避免数据竞争。

通过合理使用上述方法,可以有效地实现互斥控制,确保多线程编程的顺利进行。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号