温馨提示×

Linux Context如何实现进程同步

小樊
38
2025-11-09 17:35:34
栏目: 智能运维

在Linux中,有多种机制可以实现进程同步,以确保多个进程能够有序地访问共享资源。以下是一些常见的进程同步方法:

1. 信号量(Semaphores)

信号量是一种计数器,用于控制多个进程对共享资源的访问。Linux提供了两种类型的信号量:

  • 命名信号量:通过semgetsemopsemctl系统调用操作。
  • 无名信号量:通过sem_initsem_waitsem_postsem_destroy函数操作。
#include <semaphore.h>
#include <pthread.h>

sem_t sem;

void* thread_func(void* arg) {
    sem_wait(&sem); // 等待信号量
    // 访问共享资源
    sem_post(&sem); // 释放信号量
    return NULL;
}

int main() {
    pthread_t threads[5];
    sem_init(&sem, 0, 1); // 初始化信号量为1

    for (int i = 0; i < 5; ++i) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }

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

    sem_destroy(&sem);
    return 0;
}

2. 互斥锁(Mutexes)

互斥锁是一种简单的同步机制,用于确保同一时间只有一个进程可以访问共享资源。Linux提供了pthread_mutex_t类型的互斥锁,并通过以下函数进行操作:

  • pthread_mutex_init:初始化互斥锁。
  • pthread_mutex_lock:锁定互斥锁。
  • pthread_mutex_unlock:解锁互斥锁。
  • pthread_mutex_destroy:销毁互斥锁。
#include <pthread.h>

pthread_mutex_t mutex;

void* thread_func(void* arg) {
    pthread_mutex_lock(&mutex); // 锁定互斥锁
    // 访问共享资源
    pthread_mutex_unlock(&mutex); // 解锁互斥锁
    return NULL;
}

int main() {
    pthread_t threads[5];
    pthread_mutex_init(&mutex, NULL);

    for (int i = 0; i < 5; ++i) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }

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

    pthread_mutex_destroy(&mutex);
    return 0;
}

3. 条件变量(Condition Variables)

条件变量用于进程间的同步,允许一个进程等待某个条件成立,而另一个进程在条件成立时通知等待的进程。Linux提供了pthread_cond_t类型的条件变量,并通过以下函数进行操作:

  • pthread_cond_init:初始化条件变量。
  • pthread_cond_wait:等待条件变量。
  • pthread_cond_signal:通知一个等待的进程。
  • pthread_cond_broadcast:通知所有等待的进程。
  • pthread_cond_destroy:销毁条件变量。
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex;
pthread_cond_t cond;
int ready = 0;

void* producer(void* arg) {
    sleep(1); // 模拟生产过程
    pthread_mutex_lock(&mutex);
    ready = 1;
    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("Consumer: Data is ready!\n");
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t producer_thread, consumer_thread;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);

    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);

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

4. 管道(Pipes)

管道是一种简单的进程间通信机制,可以用于进程间的同步。管道分为匿名管道和命名管道(FIFO)。

匿名管道

匿名管道通常用于父子进程之间的通信。

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

int main() {
    int pipefd[2];
    char buffer[10];

    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    }

    if (pid == 0) { // 子进程
        close(pipefd[1]); // 关闭写端
        read(pipefd[0], buffer, sizeof(buffer));
        printf("Child received: %s\n", buffer);
        close(pipefd[0]);
    } else { // 父进程
        close(pipefd[0]); // 关闭读端
        write(pipefd[1], "Hello from parent", 18);
        close(pipefd[1]);
    }

    return 0;
}

命名管道(FIFO)

命名管道可以在不相关的进程之间进行通信。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    const char* fifo_name = "/tmp/myfifo";
    mkfifo(fifo_name, 0666);

    int fd = open(fifo_name, O_RDWR);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    char buffer[10];
    read(fd, buffer, sizeof(buffer));
    printf("Received: %s\n", buffer);

    close(fd);
    unlink(fifo_name);
    return 0;
}

这些是Linux中实现进程同步的一些常见方法。根据具体的需求和场景,可以选择合适的同步机制。

0