定时器的使用和线程安全

       在linux下如果对定时要求不太精确的话,使用alarm()和signal()就行了;

       但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。

核心api:

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);

调用成功返回0,否则返回-1;

which为定时器类型,setitimer支持3种类型的定时器:

ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。

ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。

ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。

第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。

//下面这两个是八股,要用计时器setitimer()就必须先配好

struct itimerval {
struct timeval it_interval;      //it_interval指定间隔时间
struct timeval it_value;        //it_value指定初始定时时间
};


struct timeval {
long tv_sec;    //秒
long tv_usec;   //微妙
};


//如果只指定it_value,就是实现一次定时
//如果it_value和it_interval都指定,则超时后,系统会重新初始化it_value为it_interval,实现重复定时
//如果两者都清零,则会清除定时器


//tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us = 1000ms

//ovalue用来保存先前的值,常设为NULL。

例子:

#include <stdio.h>
 #include <sys/time.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
 
 void call_back(int sig)
 {
     static int count = 1;
     printf("call_back : %d
", count++);
 }
 
 int main(void)
 {
     signal(SIGALRM, call_back);
     struct itimerval new_value;
     memset(&new_value, 0, sizeof(new_value));
 
     new_value.it_interval.tv_sec = 1;   //设置再次定时时间为1S
     new_value.it_interval.tv_usec = 0;
     new_value.it_value.tv_sec = 2;      //设置首次定时时间为2S
     new_value.it_value.tv_usec = 0;
 
     int ret = setitimer(ITIMER_REAL, &new_value, NULL);
     if (0 != ret)
     {
         perror("setitimer");
         exit(-1);
     }
     getchar();
 
     return 0;
 }

线程安全:

定时器死了,死循环就停不了,线程退出不了,还有就是主程序退出时,你的这个线程怎么安全退出。

还有就是实际的延时的问题,线程实际的输出时间比设定的长或者短。 

这里要特别注意一下sleep()和大写的Sleep()还有usleep()的时间单位是不同的,秒,毫秒和微秒

C#中定时器和多线程是常用的并发编程工具。定时器用于在指定的时间间隔内执行某个任务,而多线程则允许同时执行多个任务。 在C#中,可以使用Timer类来创建定时器。Timer类有两种类型:System.Timers.Timer和System.Threading.Timer。System.Timers.Timer是基于事件的定时器,适用于Windows Forms和WPF应用程序。System.Threading.Timer是基于线程池的定时器,适用于所有类型的应用程序。 下面是一个使用System.Timers.Timer的示例: ```csharp using System; using System.Timers; class Program { static void Main() { Timer timer = new Timer(1000); // 创建一个1秒的定时器 timer.Elapsed += TimerElapsed; // 绑定定时器事件 timer.Start(); // 启动定时器 Console.WriteLine("按任意键停止定时器..."); Console.ReadKey(); timer.Stop(); // 停止定时器 } static void TimerElapsed(object sender, ElapsedEventArgs e) { Console.WriteLine("定时器触发,当前时间:{0}", e.SignalTime); } } ``` 多线程在C#中使用Thread类来创建和管理线程。以下是一个使用线程的示例: ```csharp using System; using System.Threading; class Program { static void Main() { Thread thread = new Thread(DoWork); // 创建一个新线程 thread.Start(); // 启动线程 Console.WriteLine("按任意键停止线程..."); Console.ReadKey(); thread.Abort(); // 终止线程 } static void DoWork() { while (true) { Console.WriteLine("线程执行中..."); Thread.Sleep(1000); // 暂停1秒 } } } ``` 以上是使用定时器和多线程的基本示例,你可以根据自己的需求进行定制和扩展。请注意,在使用线程时要小心处理线程安全性和资源共享的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值