在Linux中,有多种机制可以实现进程同步,以确保多个进程能够有序地访问共享资源。以下是一些常见的进程同步方法:
信号量是一种计数器,用于控制多个进程对共享资源的访问。Linux提供了两种类型的信号量:
semget、semop和semctl系统调用操作。sem_init、sem_wait、sem_post和sem_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;
}
互斥锁是一种简单的同步机制,用于确保同一时间只有一个进程可以访问共享资源。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;
}
条件变量用于进程间的同步,允许一个进程等待某个条件成立,而另一个进程在条件成立时通知等待的进程。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;
}
管道是一种简单的进程间通信机制,可以用于进程间的同步。管道分为匿名管道和命名管道(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;
}
命名管道可以在不相关的进程之间进行通信。
#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中实现进程同步的一些常见方法。根据具体的需求和场景,可以选择合适的同步机制。