Linux的C语言编程,如何在一个进程里用signal设置2个2ms定时器,其中一个触发时打印“触发定时器1”,另外一个触发时打印“出发定时器2”,并且这两个定时器回调函数是两个不同的函数,请给出具体的代码并加以说明
时间: 2024-12-11 13:31:57 浏览: 11
在Linux C语言编程中,你可以利用`<signal.h>`库来处理信号,特别是通过`sigset_t`结构和`timerfd_create`系统调用来设置定时器。下面是一个简单的示例,展示了如何在一个进程中设置两个2毫秒的定时器,每个定时器有一个单独的回调函数:
```c
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
// 定义回调函数
void timer1_callback(int signum) {
printf("触发定时器1\n");
}
void timer2_callback(int signum) {
printf("触发定时器2\n");
}
int main() {
// 创建两个文件描述符用于定时器
int t1_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (t1_fd == -1) {
perror("创建timer1_fd失败");
return 1;
}
int t2_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (t2_fd == -1) {
perror("创建timer2_fd失败");
close(t1_fd);
return 1;
}
// 设置信号处理器
struct sigaction action1, action2;
memset(&action1, 0, sizeof(action1));
memset(&action2, 0, sizeof(action2));
action1.sa_handler = timer1_callback;
action2.sa_handler = timer2_callback;
sigemptyset(&action1.sa_mask);
sigemptyset(&action2.sa_mask);
action1.sa_flags = SA_RESTART;
action2.sa_flags = SA_RESTART;
if (sigaction(SIGRTMIN+1, &action1, NULL) < 0) {
perror("设置timer1的信号处理器");
close(t2_fd);
close(t1_fd);
return 1;
}
if (sigaction(SIGRTMIN+2, &action2, NULL) < 0) {
perror("设置timer2的信号处理器");
close(t2_fd);
close(t1_fd);
return 1;
}
// 设置定时器
struct itimerspec itspec1, itspec2;
itspec1.it_value.tv_nsec = 2 * 1000 * 1000; // 2ms
itspec1.it_interval.tv_nsec = itspec1.it_value.tv_nsec; // 持续2ms
itspec2.it_value.tv_nsec = 2 * 1000 * 1000; // 同样2ms
itspec2.it_interval.tv_nsec = itspec2.it_value.tv_nsec; // 持续2ms
if (clock_gettime(CLOCK_MONOTONIC, &itspec1.it_value) < 0 ||
clock_gettime(CLOCK_MONOTONIC, &itspec2.it_value) < 0) {
perror("获取时间戳失败");
close(t2_fd);
close(t1_fd);
return 1;
}
if (timerfd_settime(t1_fd, 0, &itspec1, NULL) < 0) {
perror("设置timer1的时间");
close(t2_fd);
close(t1_fd);
return 1;
}
if (timerfd_settime(t2_fd, 0, &itspec2, NULL) < 0) {
perror("设置timer2的时间");
close(t2_fd);
close(t1_fd);
return 1;
}
printf("定时器已设置,等待定时器触发...\n");
// 阻塞主循环,直到定时器触发
while (true) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(t1_fd, &fds);
FD_SET(t2_fd, &fds);
struct timeval tv = {0, 500000}; // 每隔500us检查一次
int result = select(FD_SETSIZE, &fds, NULL, NULL, &tv);
if (result == -1 && errno != EINTR) {
perror("select出错");
break;
} else if (result > 0) {
if (FD_ISSET(t1_fd, &fds)) {
timer1_callback(SIGRTMIN+1);
} else if (FD_ISSET(t2_fd, &fds)) {
timer2_callback(SIGRTMIN+2);
}
}
}
close(t1_fd);
close(t2_fd);
return 0;
}
```
在这个例子中,我们首先创建了两个`timerfd`文件描述符,然后分别设置了它们的信号处理器(`timer1_callback`和`timer2_callback`)。接着,我们设置两个定时器,每个定时器的间隔都是2毫秒,并在信号处理器中处理相应的信号。最后,通过`select`循环阻塞地等待定时器触发。
阅读全文