信号量与共享内存结合实现互发互收,并在进程中加上信号捕获,如果进程捕获到2号信号,删除信号量,并让对端程序正常退出使用c语言编写 代码 要有两个程序
时间: 2024-09-11 09:04:23 浏览: 67
在多进程环境下,使用信号量与共享内存实现进程间通信(IPC)是一种常见的方法。信号量用于同步多个进程对共享资源的访问,而共享内存则为这些进程提供一个共同的存储空间。在C语言中,我们可以使用POSIX标准的`sem_init`和`shm_open`等函数来创建信号量和共享内存。
以下是一个简单的示例,展示了如何结合信号量和共享内存来实现两个进程间的互斥访问和通信。同时,其中一个进程会设置信号处理函数来响应用户发送的信号(例如SIGINT,即信号编号为2),在接收到该信号时执行相应的清理操作。
首先是发送端程序(producer.c):
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <signal.h>
#define SHM_NAME "/my_shm"
#define SEM_NAME "/my_sem"
#define SIZE 1024
int running = 1;
sem_t *sem;
void signal_handler(int sig) {
if (sig == 2) {
sem_unlink(SEM_NAME);
munmap(sem, sizeof(*sem));
sem = NULL;
running = 0;
printf("Received signal, removing semaphore.\n");
}
}
int main() {
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open");
exit(EXIT_FAILURE);
}
// Set signal handler
signal(SIGINT, signal_handler);
int shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd, SIZE);
void *shm_base = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shm_base == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
// Producer loop
while (running) {
sem_wait(sem); // Acquire the semaphore
printf("Producing data...\n");
// Place data in shared memory
sem_post(sem); // Release the semaphore
sleep(1); // Artificial delay
}
// Cleanup
munmap(shm_base, SIZE);
close(shm_fd);
shm_unlink(SHM_NAME);
sem_close(sem);
return 0;
}
```
然后是接收端程序(consumer.c):
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <semaphore.h>
#define SHM_NAME "/my_shm"
#define SEM_NAME "/my_sem"
#define SIZE 1024
sem_t *sem;
int main() {
sem = sem_open(SEM_NAME, 0);
if (sem == SEM_FAILED) {
perror("sem_open");
exit(EXIT_FAILURE);
}
int shm_fd = shm_open(SHM_NAME, O_RDONLY, 0);
void *shm_base = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (shm_base == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
// Consumer loop
while (1) {
sem_wait(sem); // Acquire the semaphore
if (shm_base) {
printf("Consuming data...\n");
// Consume data from shared memory
}
sem_post(sem); // Release the semaphore
sleep(1); // Artificial delay
}
// Cleanup
munmap(shm_base, SIZE);
close(shm_fd);
shm_unlink(SHM_NAME);
sem_close(sem);
return 0;
}
```
在实际使用中,这两个程序应该分别在不同的终端或通过守护进程的方式启动。发送端程序在接收到信号后会删除信号量,并在下一次循环中检查`running`变量,如果为0则退出循环,并执行清理操作。接收端程序在尝试访问共享内存时,如果没有正确清理,可能会遇到段错误,因此在实际应用中需要确保共享内存的同步和正确的清理机制。
阅读全文