C语言 使用共享内存和信号量处理 SIGINT



我试图编写一个共享内存和信号量程序,该程序一直运行到按下Ctrl+C为止,即 收到SIGINT

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#define SHM_NAME "/shm"
#define SEM_1 "/sem_1"
#define SEM_2 "/sem_2"
#define SEM_3 "/sem_3"
static volatile sig_atomic_t run;
struct sharedMemory{
int done;
};
static struct sharedMemory *shared;
static void handleSIGINT(int sig){
if(sig == SIGINT){
printf(" SIGINT caught: sig = %dn", sig);
shared->done = 1;
run = 1;
}
}
int main(int argc, char *argv[])
{
// setup shared memory and semaphores
int shmfd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 0600);
if (shmfd == -1){
// handle error 
}
if (ftruncate(shmfd, sizeof(struct sharedMemory)) == -1){
// handle error 
}
shared = mmap(NULL, sizeof(*shared), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
if (shared == MAP_FAILED){
// close resources
}
sem_t *sem_read = sem_open(SEM_1, O_CREAT | O_EXCL, 0600, 0);
sem_t *sem_write = sem_open(SEM_2, O_CREAT | O_EXCL, 0600, BUFFER_SIZE);
// sem open error handling
if (sem_read == SEM_FAILED)
// close resources 
if (sem_write == SEM_FAILED)
// close resources 
// settup signal handler
signal(SIGINT, handleSIGINT);
while (!run)
{
sem_wait(sem_read);
// read from shared memory and store data or set shared->done to 1 to stop generator process
sem_post(sem_write);
}
// close resources
printf("exitingn");
exit(EXIT_SUCCESS);
}

当按下Ctrl+Cvolatilerun设置为1并脱离循环并退出。这在没有共享内存和信号量的情况下工作正常,但在这里我从来没有exitingstdout只有SIGINT caught: sig = 2字符串,它继续运行。

为什么?

您看到的行为的原因是信号处理程序的安装方式:

signal(SIGINT, handleSIGINT);

默认情况下,signal启用SA_RESTART标志。这意味着sem_wait将在调用信号处理程序后重新启动。

这是使用sigaction而不是signal的主要原因之一。将上面的行更改为下面的代码,它应该可以根据需要工作。

struct sigaction saction;
saction.sa_handler = handleSIGINT;
sigemptyset(&saction.sa_mask);
saction.sa_flags = 0;
sigaction (SIGINT, &saction, NULL);

不是问题中的直接部分,但建议在SEM_1SEM_2上调用sem_unlink,并检查sem_open调用的返回值。由于O_EXCL是在sem_open中设置的,因此如果在强制终止先前的调用后再次运行该程序,它将失败kill.

最新更新