sleep的作用无需多说,几乎每种语言都提供了类似的函数,调用起来也很简单。sleep的作用无非是让程序等待若干时间,而为了达到这样的目的,其实有很多种方式,最简单的往往也是最粗暴的,我们就以下面这段代码来举例说明(注:本文提及的程序编译运行环境为Linux)
/* filename: test.cpp */
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
class TestServer
{
public:
TestServer() : run_(true) {};
~TestServer(){};
void Start()
{
pthread_create(&thread_, NULL, ThreadProc, (void*)this);
}
void Stop()
{
run_ = false;
}
void Wait()
{
pthread_join(thread_, NULL);
}
void Proc()
{
int count = 0;
while (run_)
{
printf("sleep count:%d\n", ++count);
sleep(5);
}
}
private:
bool run_;
pthread_t thread_;
static void* ThreadProc(void* arg)
{
TestServer* me = static_cast<TestServer*>(arg);
me->Proc();
return NULL;
}
};
TestServer g_server;
void StopService()
{
g_server.Stop();
}
void StartService()
{
g_server.Start();
g_server.Wait();
}
void SignalHandler(int sig)
{
switch(sig)
{
case SIGINT:
StopService();
default:
break;
}
}
int main(int argc, char* argv[])
{
signal(SIGINT, SignalHandler);
StartService();
return 0;
}
</div>
这段代码描述了一个简单的服务程序,为了简化我们省略了服务的处理逻辑,也就是Proc函数的内容,这里我们只是周期性的打印某条语句,为了达到周期性的目的,我们用sleep来实现,每隔5秒钟打印一次。在main函数中我们对SIGINT信号进行了捕捉,当程序在终端启动之后,如果你输入ctr+c,这会向程序发送中断信号,一般来说程序会退出,而这里我们捕捉到了这个信号,会按我们自己的逻辑来处理,也就是调用server的Stop函数。执行编译命令
$ g++ test.cpp -o test -lpthread
</div>
然后在终端输入./test运行程序,这时程序每隔5秒会在屏幕上打印一条语句,按下ctl+c,你会发现程序并没有立即退出,而是等待了一会儿才退出,究其原因,当按下ctl+c发出中断信号时,程序捕捉到并执行自己的逻辑,也就是调用了server的Stop函数,运行标记位run_被置为false,Proc函数检测到run_为false则退出循环,程序结束,但有可能(应该说大多数情况都是如此)此时Proc正好执行到sleep那一步,而sleep是将程序挂起,由于我们捕捉到了中断信号,因此它不会退出,而是继续挂起直到时间满足为止。这个sleep显然显得不够优雅,下面介绍两种能快速退出的方式。
自定义sleep
在我们调用系统提供的sleep时我们是无法在函数内部做其它事情的,基于此我们就萌生出一种想法,如果在sleep中能够检测到退出变量,那岂不是就能快速退出了,没错,事情就是这样子的,通过自定义sleep,我们将时间片分割成更小的片段,每隔一个片段检测一次,这样就能将程序的退出延迟时间缩小为这个更小的片段,自定义的sleep如下
void sleep(int seconds, const bool* run)
{
int count = seconds * 10;
while (*run && count > 0)
{
--count;
usleep(100000);
}
}
</div>
需要注意的是,这个sleep的第二个参数必须是指针类型的,因为我们需要检测到它的实时值,而不只是使用它传入进来的值,相应的函数调用也得稍作修改,完整的代码如下
/* filename: test2.cpp */
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
class TestServer
{
public:
TestServer() : run_(true) {};
~TestServer(){};
void Start()
{
pthread_create(&thread_, NULL, ThreadProc, (void*)this);
}
void Stop()
{
run_ = false;
}
void Wait()
{
pthread_join(thread_, NULL);
}
void Proc()
{
int count = 0;
while (run_)
{
printf("sleep count:%d\n", ++count);
sleep(5, &run_);
&nb