linux

Linux进程同步:避免资源竞争的方法

小樊
38
2025-05-19 10:15:15
栏目: 智能运维

在Linux系统中,为了避免多个进程同时访问共享资源导致的资源竞争问题,可以采用以下几种方法:

1. 文件锁(File Locking)

文件锁是一种通过操作系统提供的机制来控制对文件的访问的方法。Linux提供了两种文件锁:

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

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

    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);
        return 1;
    }

    // 执行临界区代码

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

    close(fd);
    return 0;
}

2. 信号量(Semaphores)

信号量是一种更高级的同步机制,可以用来控制对共享资源的访问。Linux提供了两种信号量:

#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int main() {
    int semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
    if (semid == -1) {
        perror("semget");
        return 1;
    }

    union semun arg;
    arg.val = 1; // 初始化信号量为1
    if (semctl(semid, 0, SETVAL, arg) == -1) {
        perror("semctl");
        semctl(semid, 0, IPC_RMID);
        return 1;
    }

    // 执行临界区代码

    struct sembuf sb;
    sb.sem_num = 0;
    sb.sem_op = -1; // 等待信号量
    sb.sem_flg = 0;

    if (semop(semid, &sb, 1) == -1) {
        perror("semop wait");
    }

    // 修改共享资源

    sb.sem_op = 1; // 释放信号量
    if (semop(semid, &sb, 1) == -1) {
        perror("semop signal");
    }

    semctl(semid, 0, IPC_RMID);
    return 0;
}

3. 互斥锁(Mutexes)

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

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

pthread_mutex_t mutex;

void* thread_func(void* arg) {
    pthread_mutex_lock(&mutex);
    // 执行临界区代码
    printf("Thread %ld is in the critical section\n", (long)arg);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

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

    for (long i = 0; i < 5; ++i) {
        if (pthread_create(&threads[i], NULL, thread_func, (void*)i) != 0) {
            perror("pthread_create");
            exit(EXIT_FAILURE);
        }
    }

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

    pthread_mutex_destroy(&mutex);
    return 0;
}

4. 条件变量(Condition Variables)

条件变量用于线程间的同步,允许一个或多个线程等待某个条件的发生。

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

pthread_mutex_t mutex;
pthread_cond_t cond;
int ready = 0;

void* producer(void* arg) {
    pthread_mutex_lock(&mutex);
    ready = 1;
    printf("Producer is producing\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("Consumer is consuming\n");
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t prod_thread, cons_thread;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&prod_thread, NULL, producer, NULL);
    pthread_create(&cons_thread, NULL, consumer, NULL);

    pthread_join(prod_thread, NULL);
    pthread_join(cons_thread, NULL);

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

5. 屏障(Barriers)

屏障用于同步多个线程,确保它们在某个点上同步。所有线程必须到达屏障点后才能继续执行。

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

#define NUM_THREADS 5
pthread_barrier_t barrier;

void* thread_func(void* arg) {
    printf("Thread %ld is waiting at the barrier\n", (long)arg);
    pthread_barrier_wait(&barrier);
    printf("Thread %ld has crossed the barrier\n", (long)arg);
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    pthread_barrier_init(&barrier, NULL, NUM_THREADS);

    for (long i = 0; i < NUM_THREADS; ++i) {
        if (pthread_create(&threads[i], NULL, thread_func, (void*)i) != 0) {
            perror("pthread_create");
            exit(EXIT_FAILURE);
        }
    }

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

    pthread_barrier_destroy(&barrier);
    return 0;
}

通过使用这些同步机制,可以有效地避免资源竞争问题,确保多个进程或线程能够安全地访问共享资源。

0
看了该问题的人还看了