在多进程编程中,如何安全地共享资源、避免竞争条件是开发者必须面对的问题。C语言信号量(Semaphore)作为IPC通信(Inter-Process Communication,进程间通信)的重要机制之一,能够有效实现进程间同步。本文将从零开始,带你深入理解并使用C语言信号量,即使是编程小白也能轻松上手!
信号量是一种用于控制多个进程对共享资源访问的同步工具。它本质上是一个计数器,用来记录可用资源的数量。当一个进程想访问共享资源时,它必须先“获取”信号量;如果信号量值大于0,则减1并继续执行;否则,进程将被阻塞,直到其他进程“释放”信号量。
在Linux系统中,我们通常使用POSIX信号量来实现进程间同步。POSIX信号量分为两类:
下面我们将编写两个简单的C程序:一个生产者(producer.c),一个消费者(consumer.c)。它们通过一个命名信号量来协调对共享资源(比如一个文件)的访问。
#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>#include <semaphore.h>#include <unistd.h>#include <string.h> // producer.cint main() { // 创建或打开一个命名信号量 sem_t *sem = sem_open("/my_semaphore", O_CREAT, 0644, 1); if (sem == SEM_FAILED) { perror("sem_open"); exit(EXIT_FAILURE); } // 获取信号量(P操作) sem_wait(sem); printf("Producer: 写入数据到共享文件...\n"); FILE *fp = fopen("shared.txt", "w"); fprintf(fp, "Hello from Producer!\n"); fclose(fp); sleep(2); // 模拟耗时操作 // 释放信号量(V操作) sem_post(sem); printf("Producer: 数据写入完成,释放信号量。\n"); // 关闭并删除信号量 sem_close(sem); sem_unlink("/my_semaphore"); return 0;} // consumer.cint main() { // 打开已存在的命名信号量 sem_t *sem = sem_open("/my_semaphore", 0); if (sem == SEM_FAILED) { perror("sem_open"); exit(EXIT_FAILURE); } // 获取信号量 sem_wait(sem); printf("Consumer: 读取共享文件中的数据...\n"); FILE *fp = fopen("shared.txt", "r"); char buffer[100]; if (fgets(buffer, sizeof(buffer), fp)) { printf("读取内容: %s", buffer); } fclose(fp); // 释放信号量 sem_post(sem); printf("Consumer: 读取完成,释放信号量。\n"); sem_close(sem); return 0;} 在终端中分别编译两个程序:
gcc -o producer producer.c -lpthreadgcc -o consumer consumer.c -lpthread 注意:链接时需加上 -lpthread,因为POSIX信号量依赖于pthread库。
然后先运行 producer,再运行 consumer:
./producer# 在另一个终端运行./consumer /my_semaphore),这是POSIX标准要求。sem_close() 和 sem_unlink(),避免资源泄漏。通过本教程,你已经掌握了如何使用C语言信号量进行IPC通信,实现了两个进程之间的安全同步。无论是开发多进程服务器、嵌入式系统,还是学习操作系统原理,POSIX信号量都是不可或缺的工具。希望你能动手实践,加深理解!
记住,掌握进程间同步技术,是迈向高级系统编程的关键一步。继续加油吧!
本文由主机测评网于2025-12-04发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025122611.html