Linux系统--多线程同步技术详解&&使用举例

一 Linux系统中,多线程同步技术主要包括以下几种:

1. **互斥锁(Mutexes)**


   - `pthread_mutex_t` 是最常用的互斥锁类型,它确保同一时间只有一个线程可以进入临界区,其他试图进入的线程将被阻塞直至锁被释放。

   #include <pthread.h>

   pthread_mutex_t mtx;
   pthread_mutex_init(&mtx, NULL);

   void critical_section() {
       pthread_mutex_lock(&mtx);
       // 临界区代码...
       pthread_mutex_unlock(&mtx);
   }

2. **自旋锁(Spinlocks)**


   - `pthread_spinlock_t` 类似于互斥锁,但是当锁被占用时,等待锁的线程会循环等待(自旋),而不是进入睡眠状态。自旋锁适用于持有时间非常短的情况,否则会导致CPU使用率过高。

   pthread_spinlock_t spinlock;
   pthread_spin_init(&spinlock, 0);

   void spin_critical_section() {
       pthread_spin_lock(&spinlock);
       // 临界区代码...
       pthread_spin_unlock(&spinlock);
   }

3. **信号量(Semaphores)**


   - `sem_t` 结构体表示信号量,可以用来控制资源的数量,允许一定数量的线程同时访问资源。

  sem_t semaphore;
   sem_init(&semaphore, 0, MAX_CONCURRENT_THREADS);

   void access_resource() {
       sem_wait(&semaphore);
       // 访问共享资源...
       sem_post(&semaphore);
   }

4. **条件变量(Condition Variables)**


   - `pthread_cond_t` 结合互斥锁使用,线程在条件不满足时可以等待,直到其他线程修改了条件并发出信号唤醒等待的线程。

pthread_mutex_t mtx;
   pthread_cond_t cond;
   pthread_mutex_init(&mtx, NULL);
   pthread_cond_init(&cond, NULL);

   void wait_condition() {
       pthread_mutex_lock(&mtx);
       while (!condition_is_met()) {
           pthread_cond_wait(&cond, &mtx);
       }
       // 条件满足时执行的代码...
       pthread_mutex_unlock(&mtx);
   }

   void signal_condition() {
       pthread_mutex_lock(&mtx);
       // 修改条件...
       pthread_cond_signal(&cond); // 或者 pthread_cond_broadcast(&cond);
       pthread_mutex_unlock(&mtx);
   }

5. **读写锁(Reader-Writer Locks)**


   - `pthread_rwlock_t` 读写锁允许多个线程同时读取资源,但在写入时会排斥所有的读取和写入。

   

   pthread_rwlock_t rwlock;
   pthread_rwlock_init(&rwlock, NULL);

   void read_access() {
       pthread_rwlock_rdlock(&rwlock);
       // 读取资源...
       pthread_rwlock_unlock(&rwlock);
   }

   void write_access() {
       pthread_rwlock_wrlock(&rwlock);
       // 写入资源...
       pthread_rwlock_unlock(&rwlock);
   }

6. **原子操作(Atomic Operations)**


   - Linux内核提供了原子操作API,例如`atomic_t`类型,用于对整数变量进行原子的增加、减少、交换等操作,避免多线程环境下的数据竞争。

此外,Linux内核层面还支持其他的同步原语,例如seqlock、RCU(Read-Copy Update)等,这些都是用于解决特定场景下的同步问题。在用户空间编程时,POSIX线程库提供的接口足以满足大多数多线程同步需求。而在内核编程中,可能会用到更底层和专用的同步机制。

二  在Linux系统中,多线程同步技术主要包括互斥锁(Mutex)、信号量(Semaphore)、条件变量(Condition Variable)、读写锁(Read-Write Lock)、自旋锁(Spinlock)、原子操作(Atomic Operations)和屏障(Barrier)。以下是这些同步技术在Linux系统中的实际使用例子:

1. **互斥锁(Mutex)**:

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;

void* thread_function(void* arg) {
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&mutex);
        counter++;
        pthread_mutex_unlock(&mutex);
    }
    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;
}

2. **信号量(Semaphore)**:

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

sem_t sem;
int counter = 0;

void* thread_function(void* arg) {
    for (int i = 0; i < 100000; i++) {
        sem_wait(&sem);
        counter++;
        sem_post(&sem);
    }
    return NULL;
}

int main() {
    sem_init(&sem, 0, 1);

    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);

    sem_destroy(&sem);
    return 0;
}

3. **条件变量(Condition Variable)**:

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int counter = 0;

void* thread_function(void* arg) {
    pthread_mutex_lock(&mutex);
    counter++;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;

    pthread_create(&thread, NULL, thread_function, NULL);

    pthread_mutex_lock(&mutex);
    while (counter == 0) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    printf("Counter: %d\n", counter);

    pthread_join(thread, NULL);
    return 0;
}

4. **读写锁(Read-Write Lock)**:

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

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int counter = 0;

void* read_thread_function(void* arg) {
    pthread_rwlock_rdlock(&rwlock);
    printf("Counter: %d\n", counter);
    pthread_rwlock_unlock(&rwlock);
    return NULL;
}

void* write_thread_function(void* arg) {
    pthread_rwlock_wrlock(&rwlock);
    counter++;
    pthread_rwlock_unlock(&rwlock);
    return NULL;
}

int main() {
    pthread_t read_thread, write_thread;

    pthread_create(&read_thread, NULL, read_thread_function, NULL);
    pthread_create(&write_thread, NULL, write_thread_function, NULL);

    pthread_join(read_thread, NULL);
    pthread_join(write_thread, NULL);

    return 0;
}

5. **自旋锁(Spinlock)**:

自旋锁通常用于内核编程,而不是用户空间程序。在用户空间程序中,使用互斥锁和其他同步原语通常更为合适。

6. **原子操作(Atomic Operations)**:

#include<stdio.h>
#include <stdbool.h>

int counter = 0;

void atomic_increment(int* value) {
    int old_value, new_value;
    do {
        old_value = *value;
        new_value = old_value + 1;
    } while (!__sync_bool_compare_and_swap(value, old_value, new_value));
}

int main() {
    for (int i = 0; i < 100000; i++) {
        atomic_increment(&counter);
    }
    printf("Counter: %d\n", counter);
    return 0;
}

7. **屏障(Barrier)**:

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

pthread_barrier_t barrier;

void* thread_function(void* arg) {
    printf("Thread %ld before barrier\n", (long)arg);
    pthread_barrier_wait(&barrier);
    printf("Thread %ld after barrier\n", (long)arg);
    return NULL;
}

int main() {
    pthread_barrier_init(&barrier, NULL, 3);

    pthread_t thread1, thread2;

    pthread_create(&thread1, NULL, thread_function, (void*)1);
    pthread_create(&thread2, NULL, thread_function, (void*)2);

    printf("Main thread before barrier\n");
    pthread_barrier_wait(&barrier);
    printf("Main thread after barrier\n");

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    pthread_barrier_destroy(&barrier);
    return 0;
}

这些实际使用例子展示了如何在Linux系统中使用不同的多线程同步技术。在实际编程中,可以根据具体需求选择合适的同步机制。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值