14 进程的定时器(与信号相关)

(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。

测试代码:


#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 = %lu\n", pthread_self());
}
void headle2(int sig)
{
	printf("headle2, tid = %lu\n", pthread_self());
}

void *work1(void *arg)
{
	struct itimerval it;
	
	signal(SIGALRM, headle);
	signal(SIGPROF, headle2);
	printf("work1 tid = %lu\n", 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("work1\n");
		sleep(1);
	}
	pthread_exit(NULL);
}
void *work2(void *arg)
{
	printf("work2 tid = %lu\n", pthread_self());
	while(1)
	{	printf("work2\n");
		sleep(1);
	}
	pthread_exit(NULL);
}
int main(int argc, char **argv)
{
	pthread_t tid1, tid2;
	printf("main tid = %lu\n", 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;
}

 

执行结果:

book@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$


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值