进程同步的方法有哪些

在操作系统中,进程同步是指在并发环境下,多个进程为了共享资源协调执行而采取的机制,确保数据的一致性正确性。由于多个进程可能同时访问共享资源,因此必须使用同步手段来避免竞态条件(Race Condition)。


🚀 常见的进程同步方法

同步方法原理适用场景是否忙等待
🔒互斥锁 (Mutex)进程间互斥访问共享资源简单的互斥控制❌ 否
📊信号量 (Semaphore)计数器机制,控制资源访问上限资源限制、访问控制✅/❌ 可选
⏳条件变量 (Condition Variable)等待-通知机制,协调线程间操作生产者-消费者模型、复杂同步场景❌ 否
📬管道 (Pipe)通过管道传输数据,实现同步父子进程间数据传输❌ 否
📨消息队列 (Message Queue)内核维护的消息链表,传递消息独立进程间的同步与数据传输❌ 否
🧠共享内存 (Shared Memory)共享内存区 + 同步机制大量数据传输 + 同步机制❌ 否
📣信号 (Signal)异步机制,通知某个进程触发事件中断、超时、异常处理❌ 否

🔒 1. 互斥锁 (Mutex)

🔹 原理

  • 互斥锁确保同一时刻仅有一个进程访问共享资源。
  • 通过 lock()unlock() 控制访问权。

🔹 特点

✅ 适用于多进程对同一资源的访问控制;
✅ 无忙等待,效率较高;
❗ 需小心死锁问题;

🔹 示例代码 (C - pthread_mutex)

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

pthread_mutex_t lock;
int counter = 0;

void* increment(void* arg) {
    for (int i = 0; i < 5; ++i) {
        pthread_mutex_lock(&lock);  // 加锁
        counter++;
        printf("线程 %ld - 计数器: %d\n", pthread_self(), counter);
        pthread_mutex_unlock(&lock);  // 解锁
        sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;

    pthread_mutex_init(&lock, NULL);

    pthread_create(&t1, NULL, increment, NULL);
    pthread_create(&t2, NULL, increment, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    pthread_mutex_destroy(&lock);

    return 0;
}

📊 2. 信号量 (Semaphore)

🔹 原理

  • 信号量维护一个计数器,表示可用资源的数量。
  • P() (wait) 操作:计数器减 1;
  • V() (signal) 操作:计数器加 1;

🔹 特点

✅ 适合控制对有限资源的访问;
✅ 适用于多进程访问同一资源的访问上限控制
❗ 可能会出现死锁,需小心处理;

🔹 示例代码 (C - sem_t)

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

sem_t semaphore;

void* threadFunc(void* arg) {
    sem_wait(&semaphore);  // 获取信号量
    printf("线程 %ld 正在访问共享资源\n", pthread_self());
    sleep(1);
    printf("线程 %ld 释放资源\n", pthread_self());
    sem_post(&semaphore);  // 释放信号量
    return NULL;
}

int main() {
    pthread_t threads[3];

    sem_init(&semaphore, 0, 2);  // 最多允许2个线程同时访问

    for(int i = 0; i < 3; i++)
        pthread_create(&threads[i], NULL, threadFunc, NULL);

    for(int i = 0; i < 3; i++)
        pthread_join(threads[i], NULL);

    sem_destroy(&semaphore);
    return 0;
}

3. 条件变量 (Condition Variable)

🔹 原理

  • 条件变量用于等待/通知机制,通常与 pthread_mutex 配合使用。
  • wait() 操作等待条件满足;
  • signal() 操作通知等待的线程继续执行;

🔹 特点

✅ 适合复杂的线程同步
✅ 常用于生产者-消费者模型
❗ 不适合大数据传输;

🔹 示例代码 (C - pthread_cond)

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

pthread_mutex_t mutex;
pthread_cond_t cond;
int ready = 0;

void* producer(void* arg) {
    pthread_mutex_lock(&mutex);
    ready = 1;  
    printf("生产者:数据已准备好\n");
    pthread_cond_signal(&cond);  
    pthread_mutex_unlock(&mutex);
    return NULL;
}

void* consumer(void* arg) {
    pthread_mutex_lock(&mutex);
    while (!ready) {
        pthread_cond_wait(&cond, &mutex);  
    }
    printf("消费者:已接收数据\n");
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t t1, t2;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&t1, NULL, producer, NULL);
    pthread_create(&t2, NULL, consumer, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

📣 4. 信号 (Signal)

🔹 原理

  • 信号是一种异步的通知机制,允许一个进程向另一个进程发送信号,告知其需要执行的操作。

🔹 常用信号

SIGINT → 中断信号 (Ctrl+C)
SIGTERM → 终止信号
SIGCHLD → 子进程终止信号

🔹 示例代码 (C - signal())

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void signalHandler(int signum) {
    printf("收到信号: %d\n", signum);
}

int main() {
    signal(SIGINT, signalHandler);  // 捕获 Ctrl+C 信号
    while (1) {
        printf("等待信号...\n");
        sleep(2);
    }
    return 0;
}

📋 5. 对比总结

方法适用场景优势劣势
互斥锁 (Mutex)简单的临界区访问控制无忙等待、简单易用不适用于多资源并发场景
信号量 (Semaphore)资源访问上限控制适用于多资源管理容易导致死锁
条件变量 (Condition Variable)线程间的等待/通知机制复杂同步场景、无忙等待需配合互斥锁使用
信号 (Signal)异步事件通知实时性高、轻量级仅适合短暂通知,不适合数据传输
共享内存 (Shared Memory)大量数据共享数据传输最快需额外借助同步机制避免数据竞争

🌟 推荐学习路径

  • 入门阶段 → 使用 MutexSemaphore 学习基础同步机制;
  • 进阶阶段 → 掌握 Condition Variable,解决更复杂的同步问题;
  • 高效场景 → 在大规模数据传输中使用 共享内存 提高性能;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值