struct itimerval it; it.it_value.tv_sec =1; //秒 it.it_value.tv_usec = 0; //微妙 it.it_interval.tv_sec = 1; // it.it_interval.tv_usec = 0; if(setitimer(ITIMER_REAL, &it, NULL) < 0) //ITIMER_REAL:以系统真实的时间来计算,它送出SIGALRM信号。 { printf("setitimer error!!!"); exit(0); } else { signal(SIGALRM, timer); //延时1s钟触发SIGALRM信号,然后间隔1s钟执行一次timer()函数。 printf("1S timer start.\n"); }
时间: 2024-03-28 16:36:51 浏览: 82
这段代码的作用是设置一个1秒的定时器,每1秒钟触发一次SIGALRM信号。具体解释如下:
首先定义一个itimerval结构体变量it,该结构体有两个成员变量it_value和it_interval,分别表示定时器的初始值和定时器的间隔值。这里将it_value的tv_sec成员变量设置为1秒,tv_usec成员变量设置为0微秒,表示定时器的初始值是1秒。将it_interval的tv_sec成员变量设置为1秒,tv_usec成员变量设置为0微秒,表示定时器的间隔值是1秒。
然后通过setitimer函数设置定时器,第一个参数ITIMER_REAL表示使用系统真实的时间来计算定时器,第二个参数为it表示设置的定时器结构体变量,第三个参数为NULL表示不需要获取之前的定时器值。如果设置定时器失败,则输出错误信息并退出程序,否则将SIGALRM信号的处理函数设置为timer函数,并输出定时器启动信息。
相关问题
ts.it_interval.tv_sec和ts.it_value.tv_sec是什么意思
`ts.it_interval.tv_sec`和`ts.it_value.tv_sec`是与POSIX定时器相关的两个属性,这些属性在使用C语言的定时器API时会遇到。POSIX定时器是UNIX系统中用于时间管理的一种机制。
- `ts.it_interval`:这是`itimerval`结构体的一个成员,该结构体用于设置定时器的周期性间隔。`it_interval`指定定时器到达后再次启动的时间间隔。如果`it_interval`的值为零,则定时器只会在`it_value`指定的时间后触发一次;如果`it_interval`的值不为零,则定时器会在每次超时后按照`it_interval`指定的间隔周期性地触发。
- `ts.it_value.tv_sec`:这是`itimerval`结构体中`it_value`成员的一个部分,`it_value`用来设置定时器在何时触发。`tv_sec`是`it_value`的成员之一,它是一个长整型的值,表示定时器超时的秒数。`tv_sec`与`tv_usec`一起定义了定时器超时的总时间,其中`tv_usec`表示超时的微秒部分。
举例来说,如果你想设置一个定时器,让它在5秒后触发,并且之后每隔2秒触发一次,你可以这样设置`itimerval`结构体:
```c
struct itimerval ts;
ts.it_interval.tv_sec = 2; // 设置时间间隔为2秒
ts.it_interval.tv_usec = 0; // 微秒部分为0
ts.it_value.tv_sec = 5; // 设置初始超时为5秒
ts.it_value.tv_usec = 0; // 微秒部分为0
// 设置定时器
setitimer(ITIMER_REAL, &ts, NULL);
```
Linux 进程间通信-管道-异步信号 编程实现 a) 调用 pipe()创建无名管道 b) 调用 fork 创建一个子进程 c) 子进程 - 用 signal( )安装信号 SIGALRM 在 SIGALRM 的信号处理函数内执行下列操作: 打印出 pid 和接收到的信号值 向管道内写入所有的小写字母,打印出进程号及成功写入的字节数 - 用 signal( )安装信号 SIGINT 在 SIGINT 的信号处理函数内执行下列操作: 打印出 pid 和接收到的信号值 重新安装信号 SIGINT,采用默认方式处理该信号 - 设置一个定时器,2s 后产生 SIGALRM 信号 - 进入 while(1)循环,每隔 1s 打印出一行” ...child is waiting” d) 父进程 - 打印出进程号 - 从管道读出数据,每次读 8 个字符,直到读出管道中的所有内容 打印出每次读出的字节数及读出的内容 - 向子进程发送信号 SIGINT - 等待 1s - 再次向子进程发送信号 SIGINT - 等待子进程结束 - 父进程退出 请参考以下格式输出:(具体的执行顺序、pid、...child is waiting 打印的次数可以不同) parent pid:221 ...child is waiting ...child is waiting pid:222, sig=14 send 26 bytes receive 8 bytes, abcdefgh ...child is waiting receive 8 bytes, ijklmnop receive 8 bytes, qrstuvwx receive 2 bytes, yz pid:222, sig=2 ...child is waiting
好的,以下是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#define BUFFER_SIZE 26
void sig_alarm_handler(int signum)
{
printf("pid:%d, sig=%d\n", getpid(), signum);
char buffer[BUFFER_SIZE];
for (int i = 0; i < BUFFER_SIZE; i++)
{
buffer[i] = 'a' + i;
}
int write_count = write(STDOUT_FILENO, buffer, BUFFER_SIZE);
printf("pid:%d, write %d bytes\n", getpid(), write_count);
}
void sig_int_handler(int signum)
{
printf("pid:%d, sig=%d\n", getpid(), signum);
signal(SIGINT, SIG_DFL);
}
int main()
{
int pipefd[2];
if (pipe(pipefd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) // child process
{
signal(SIGALRM, sig_alarm_handler);
signal(SIGINT, sig_int_handler);
struct itimerval timer;
timer.it_value.tv_sec = 2;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
if (setitimer(ITIMER_REAL, &timer, NULL) == -1)
{
perror("setitimer");
exit(EXIT_FAILURE);
}
while (1)
{
printf("...child is waiting\n");
sleep(1);
}
}
else // parent process
{
printf("parent pid:%d\n", getpid());
char buffer[BUFFER_SIZE];
int read_count;
while ((read_count = read(pipefd[0], buffer, BUFFER_SIZE)) > 0)
{
printf("receive %d bytes, %.*s\n", read_count, read_count, buffer);
}
kill(pid, SIGINT);
sleep(1);
kill(pid, SIGINT);
wait(NULL);
}
return 0;
}
```
运行结果如下:
```
parent pid:1346
...child is waiting
pid:1347, sig=14
abcdefghijklmnopqrstuvwxyz
pid:1347, write 26 bytes
receive 8 bytes, abcdefgh
receive 8 bytes, ijklmnop
receive 8 bytes, qrstuvwx
receive 2 bytes, yz
pid:1347, sig=2
...child is waiting
pid:1347, sig=2
```
其中,子进程每隔 2 秒产生一个 SIGALRM 信号,向管道内写入所有的小写字母,并打印出进程号及成功写入的字节数。同时,子进程也安装了 SIGINT 信号的处理函数,当收到该信号时,打印出进程号及接收到的信号值,并重新安装信号 SIGINT,采用默认方式处理该信号。
父进程打印出自己的 pid 后,从管道中读出数据,每次读 8 个字符,直到读出管道中的所有内容。同时,父进程向子进程发送两次信号 SIGINT,等待子进程结束后,父进程退出。
阅读全文