sleep函数使用时应注意的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MBuger/article/details/79761059

简介

很多时候,当我们需要暂停程序执行的流程的时候,往往会使用sleep函数。例如下面函数。

int mian()
{
    int a = 0;
    Sleep(5)
    printf("%d", a)
    return 0;
}

暂停5秒之后输出a。乍一看好像没有什么问题。在效果上可能也没有什么问题。但是在真正的生产环境下使用sleep函数很有可能会带来一些很难发现的问题。所以用sleep函数一定要考虑清楚。

原因

当调用Sleep函数的时候,比如Sleep(5),告诉系统,此线程将放弃此次运行的时间片,比方说现在线程只执行了10s,按规定它被唤醒一次是要执行20s的。这时它就说,这次机会我放弃,后面的10s不要了。下次轮上我再叫我。 这样,系统便会将其终止,然后再一次进行调度选择。如果它运气很好,又被选中了,系统则会查看这个线程是否处于sleep标志中。如果发现他还需要继续睡眠,则重新进行调度选择,直到选择一个有权执行的线程为止。 如果很不幸,5s到了,但是系统很忙,调度算法在很长一段时间也没有选择到这个线程,那这么线程就很继续休眠。于是说,这个Sleep(5);将导致这个线程会休眠大于等于5s的时间。

解决方法

当我们真的需要暂缓程序的流程的时候不一定非要把进程置于sleep状态,阻塞住它就行了,当然这一定意义上也会降低一些CPU的使用率,但是可以保证延时时间的准确性。例如在go语言中就给出了这样的方法。

func main(){
    var a int
    var delay <-chan time.Time
    delay := time.Tick(5*time.Second)
    <-delay
    fmt.Println(a)
}

这里就使用了一个时间chan阻塞住了程序的流程。

猜你喜欢

转载自blog.csdn.net/MBuger/article/details/79761059