使用互斥锁处理资源竞争
- 原理:互斥锁(Mutex)用于保证在同一时间只有一个线程或进程能够访问共享资源,从而避免资源竞争。
- C语言示例:
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
pthread_mutex_t mutex;
int fd;
void* read_file(void* arg) {
pthread_mutex_lock(&mutex);
char buffer[1024];
// 设置为非阻塞I/O
fcntl(fd, F_SETFL, O_NONBLOCK);
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read == -1 && errno == EAGAIN) {
// 处理非阻塞I/O没有数据可读的情况
printf("No data available yet\n");
} else if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("Read data: %s\n", buffer);
}
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t thread;
pthread_mutex_init(&mutex, NULL);
fd = open("test.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
pthread_create(&thread, NULL, read_file, NULL);
pthread_join(thread, NULL);
close(fd);
pthread_mutex_destroy(&mutex);
return 0;
}
使用信号量处理资源竞争
- 原理:信号量(Semaphore)可以控制同时访问共享资源的线程或进程数量。它通过一个计数器来实现,当计数器大于0时,线程或进程可以获取信号量(计数器减1)并访问资源,当计数器为0时,获取操作将阻塞。
- C语言示例:
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <semaphore.h>
sem_t sem;
int fd;
void* read_file(void* arg) {
sem_wait(&sem);
char buffer[1024];
// 设置为非阻塞I/O
fcntl(fd, F_SETFL, O_NONBLOCK);
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read == -1 && errno == EAGAIN) {
// 处理非阻塞I/O没有数据可读的情况
printf("No data available yet\n");
} else if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("Read data: %s\n", buffer);
}
sem_post(&sem);
return NULL;
}
int main() {
pthread_t thread;
sem_init(&sem, 0, 1);
fd = open("test.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
pthread_create(&thread, NULL, read_file, NULL);
pthread_join(thread, NULL);
close(fd);
sem_destroy(&sem);
return 0;
}
总结
- 在多线程或多进程并发执行非阻塞I/O操作时,互斥锁和信号量是有效处理资源竞争的机制。
- 互斥锁适合于一次只允许一个线程或进程访问共享资源的场景,而信号量则更灵活,可以控制同时访问资源的数量。
- 在非阻塞I/O错误处理方面,通过检查
errno
是否为EAGAIN
来判断是否没有数据可读,从而进行相应的处理,确保程序的正确性和稳定性。