(14)定时器与信号(glibc定时器timer)
(0)注意:
1. alarm()函数和setitimer()函数都不能用于多线程中对子线程定时。因为即使信号函数在子线程中 安装,即使定时器在子线程中初始化;当信号产生时,主线程永远都会捕捉信号。
2.对于想要控制指定子线程1的执行时间,需要在子线程1中再创建一个线程2。子线程2过了时间time后,通过pthread_kill向线程1发送信号, 线程1捕捉这个信号。(参考我博文: https://blog.csdn.net/qq_38813056/article/details/86531820)
(1)unsigned int alarm(unsigned int seconds);
0.成功:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
1.在进程中设置一个定时器,当定时器指定的时间到时,它向进程发送SIGALRM信号
2.默认方式其动作是终止调用该alarm函数的进程。
3.一个进程只能有一个闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。
4.需要注意的是,经过指定的秒数后,信号由内核产生,由于进程调度的延迟,所以进程得到控制从而能够处理该信号还需要一些时间。
(2)int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
which为定时器类型:
ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
value: 是结构itimerval的一个实例
struct timeval {
long tv_sec; // tv_sec提供秒级精度
long tv_usec; // tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us。
};
struct itimerval {
struct timeval it_interval; // 指定间隔时间。
struct timeval it_value; // 指定初始定时时间
};
1.如果只指定it_value,就是实现一次定时;
2.如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;
3.两者都清零,则会清除定时器。
4.如果用ITIMER_REAL宏, 将覆盖alarm函数设置的定时器
ovalue: 用来保存先前的值,常设为NULL。
测试代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58#include <stdio.h> #include <stdbool.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <errno.h> #include "list.h" #include <sys/time.h> #include <signal.h> #include <pthread.h> void headle(int sig) { printf("headle, tid = %lun", pthread_self()); } void headle2(int sig) { printf("headle2, tid = %lun", pthread_self()); } void *work1(void *arg) { struct itimerval it; signal(SIGALRM, headle); signal(SIGPROF, headle2); printf("work1 tid = %lun", pthread_self()); memset(&it, 0, sizeof(struct itimerval)); it.it_value.tv_sec = 1; it.it_interval.tv_sec = 1; alarm(1); setitimer(ITIMER_PROF, &it, NULL); while(1) { printf("work1n"); sleep(1); } pthread_exit(NULL); } void *work2(void *arg) { printf("work2 tid = %lun", pthread_self()); while(1) { printf("work2n"); sleep(1); } pthread_exit(NULL); } int main(int argc, char **argv) { pthread_t tid1, tid2; printf("main tid = %lun", pthread_self()); pthread_create(&tid1, NULL, work1, NULL); //pthread_create(&tid2, NULL, work2, NULL); //pthread_join(tid1, NULL); while(1); //pthread_join(tid2, NULL); return 0; }
执行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23book@gui_hua_shu:~/test/pool$ ./a.out main tid = 140211890853632 work1 tid = 140211882542848 work1 headle, tid = 140211890853632 work1 headle2, tid = 140211890853632 headle2, tid = 140211890853632 work1 work1 headle2, tid = 140211890853632 headle2, tid = 140211890853632 work1 headle2, tid = 140211890853632 work1 headle2, tid = 140211890853632 work1 ^C book@gui_hua_shu:~/test/pool$
最后
以上就是顺利画板最近收集整理的关于14 进程的定时器(与信号相关)的全部内容,更多相关14内容请搜索靠谱客的其他文章。
发表评论 取消回复