Bootstrap

HoRain云--Linux线程ID与互斥、同步机制详解(附代码示例)

  

🎬 HoRain 云小助手个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

一、线程ID:线程的唯一身份证

关键函数:

二、互斥锁(Mutex):解决数据竞争

核心操作:

示例:线程安全的计数器

三、条件变量(Condition Variable):线程间的信号灯

核心操作:

示例:生产者-消费者模型

四、总结


在多线程编程中,线程管理、数据同步是开发者必须掌握的核心技能。本文将通过浅显易懂的方式,结合代码示例讲解Linux线程ID、**互斥锁(Mutex)条件变量(Condition Variable)**的使用。


一、线程ID:线程的唯一身份证

每个线程在创建时都会被分配一个唯一的线程ID(类型为pthread_t),类似于进程的PID。通过线程ID,我们可以对特定线程进行操作(如取消线程)。

关键函数:
  • 获取当前线程IDpthread_self()
  • 比较线程IDpthread_equal(tid1, tid2)
#include <pthread.h>
#include <stdio.h>

void* thread_func(void* arg) {
    pthread_t tid = pthread_self();
    printf("Thread ID: %lu\n", (unsigned long)tid);
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);
    printf("Main thread ID: %lu\n", (unsigned long)pthread_self());
    pthread_join(tid, NULL);
    return 0;
}

注意pthread_t的具体实现可能不同(可能为结构体),因此必须使用pthread_equal比较线程ID,不能直接用==


二、互斥锁(Mutex):解决数据竞争

当多个线程同时访问共享资源时,可能导致数据竞争(Data Race)。互斥锁通过“加锁”机制确保同一时间只有一个线程访问临界区。

核心操作:
  • 初始化pthread_mutex_init()
  • 加锁pthread_mutex_lock()
  • 解锁pthread_mutex_unlock()
  • 销毁pthread_mutex_destroy()
示例:线程安全的计数器
#include <pthread.h>
#include <stdio.h>

int counter = 0;
pthread_mutex_t mutex;

void* increment(void* arg) {
    for (int i = 0; i < 100000; ++i) {
        pthread_mutex_lock(&mutex);
        counter++; // 临界区
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_mutex_init(&mutex, NULL);
    pthread_t t1, t2;
    
    pthread_create(&t1, NULL, increment, NULL);
    pthread_create(&t2, NULL, increment, NULL);
    
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    
    printf("Final counter: %d\n", counter); // 正确输出200000
    pthread_mutex_destroy(&mutex);
    return 0;
}

若不加锁:最终结果可能小于200000,因为两个线程可能同时读取旧值并写入。


三、条件变量(Condition Variable):线程间的信号灯

条件变量用于线程间的协同工作,典型场景是“生产者-消费者”模型。它需要与互斥锁配合使用。

核心操作:
  • 等待条件pthread_cond_wait(cond, mutex)
  • 通知条件pthread_cond_signal(cond)(唤醒一个线程)或pthread_cond_broadcast(cond)(唤醒所有线程)
示例:生产者-消费者模型
#include <pthread.h>
#include <stdio.h>

int data = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;

void* producer(void* arg) {
    pthread_mutex_lock(&mutex);
    data = 42; // 生产数据
    printf("Produced data: %d\n", data);
    pthread_cond_signal(&cond); // 通知消费者
    pthread_mutex_unlock(&mutex);
    return NULL;
}

void* consumer(void* arg) {
    pthread_mutex_lock(&mutex);
    while (data == 0) { // 必须用循环避免虚假唤醒
        pthread_cond_wait(&cond, &mutex);
    }
    printf("Consumed data: %d\n", data);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    
    pthread_t t_producer, t_consumer;
    pthread_create(&t_consumer, NULL, consumer, NULL);
    pthread_create(&t_producer, NULL, producer, NULL);
    
    pthread_join(t_producer, NULL);
    pthread_join(t_consumer, NULL);
    
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

四、总结

  1. 线程ID是线程的唯一标识,不可直接比较。
  2. 互斥锁解决数据竞争问题,确保临界区原子性。
  3. 条件变量用于线程间协同,需配合互斥锁使用。

注意事项

  • 加锁后必须及时解锁,避免死锁。
  • 条件变量等待必须使用while循环检查条件(防止虚假唤醒)。

掌握这些基础同步机制后,可以更安全地开发高效的多线程程序。建议动手运行示例代码,观察不同场景的输出结果!

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

;