温馨提示×

Linux Context如何实现进程互斥

小樊
44
2025-11-09 17:36:24
栏目: 智能运维

在Linux中,实现进程互斥(即确保多个进程不会同时访问共享资源)的方法有多种。以下是一些常用的方法:

1. 文件锁(File Locking)

文件锁是一种通过操作系统提供的机制来控制对文件的访问。Linux提供了两种类型的文件锁:建议性锁(Advisory Locks)和强制性锁(Mandatory Locks)。

  • 建议性锁:进程可以选择是否遵守锁的约定。通常使用fcntl系统调用来实现。
  • 强制性锁:操作系统强制执行锁的规则,即使进程不遵守约定也会被阻止。
#include <sys/file.h>
#include <unistd.h>

int fd = open("lockfile", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
    perror("open");
    exit(EXIT_FAILURE);
}

// 设置建议性锁
struct flock lock;
lock.l_type = F_WRLCK; // 写锁
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0; // 锁定整个文件

if (fcntl(fd, F_SETLK, &lock) == -1) {
    perror("fcntl");
    close(fd);
    exit(EXIT_FAILURE);
}

// 执行临界区代码

// 释放锁
lock.l_type = F_UNLCK;
if (fcntl(fd, F_SETLK, &lock) == -1) {
    perror("fcntl");
}

close(fd);

2. 信号量(Semaphores)

信号量是一种更高级的同步机制,可以用来控制对共享资源的访问。Linux提供了两种类型的信号量:命名信号量(Named Semaphores)和无名信号量(Unnamed Semaphores)。

  • 命名信号量:通过名称来标识,可以在不同进程之间共享。
  • 无名信号量:只能在创建它的进程中使用。
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>

sem_t *sem = sem_open("/my_semaphore", O_CREAT, 0666, 1);
if (sem == SEM_FAILED) {
    perror("sem_open");
    exit(EXIT_FAILURE);
}

// 等待信号量
if (sem_wait(sem) == -1) {
    perror("sem_wait");
    sem_close(sem);
    exit(EXIT_FAILURE);
}

// 执行临界区代码

// 释放信号量
if (sem_post(sem) == -1) {
    perror("sem_post");
}

sem_close(sem);
sem_unlink("/my_semaphore");

3. 互斥锁(Mutexes)

互斥锁是一种简单的同步机制,用于保护临界区。Linux提供了pthread_mutex_t类型的互斥锁。

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *thread_func(void *arg) {
    pthread_mutex_lock(&mutex);
    // 执行临界区代码
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    if (pthread_create(&thread1, NULL, thread_func, NULL) != 0) {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&thread2, NULL, thread_func, NULL) != 0) {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }

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

    pthread_mutex_destroy(&mutex);
    return 0;
}

4. 条件变量(Condition Variables)

条件变量通常与互斥锁一起使用,用于线程间的同步。它们允许线程在某个条件满足时等待,并在条件改变时被唤醒。

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

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

void *thread_func(void *arg) {
    pthread_mutex_lock(&mutex);
    while (!ready) {
        pthread_cond_wait(&cond, &mutex);
    }
    // 执行临界区代码
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;

    if (pthread_create(&thread, NULL, thread_func, NULL) != 0) {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }

    // 模拟一些工作
    sleep(2);

    pthread_mutex_lock(&mutex);
    ready = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);

    pthread_join(thread, NULL);

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

这些方法各有优缺点,选择哪种方法取决于具体的应用场景和需求。文件锁适用于跨进程的同步,信号量和互斥锁适用于同一进程内的线程同步,而条件变量则常用于复杂的同步场景。

0