在Linux系统中,为了避免多个进程同时访问共享资源导致的资源竞争问题,可以采用以下几种方法:
文件锁是一种通过操作系统提供的机制来控制对文件的访问的方法。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;
}
信号量是一种更高级的同步机制,可以用来控制对共享资源的访问。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;
}
互斥锁是一种简单的同步机制,用于保护临界区代码。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;
}
条件变量用于线程间的同步,允许一个或多个线程等待某个条件的发生。
#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;
}
屏障用于同步多个线程,确保它们在某个点上同步。所有线程必须到达屏障点后才能继续执行。
#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;
}
通过使用这些同步机制,可以有效地避免资源竞争问题,确保多个进程或线程能够安全地访问共享资源。