-
直接转换 sleep 函数至模块结构图的数据流图方法
资源介绍
10.19 sleep函数
在本书的很多例子中都已使用了 s h e e p函数,在程序 1 0 - 4和1 0 - 5中有两个 s l e e p的很完善的
实现。
#include
unsigned int sleep(unsigned int s e c o n d s) ;
返回:0或未睡的秒数
此函数使调用进程被挂起直到:
(1) 已经过了s e c o n d s所指定的墙上时钟时间,或者
(2) 该进程捕捉到一个信号并从信号处理程序返回。
如同a l a r m信号一样,由于某些系统活动,实际返回时间比所要求的会迟一些。
在第( 1 )种情形,返回值是0。当由于捕捉到某个信号 s l e e p提早返回时(第 ( 2 )种情形),返
回值是未睡足的秒数(所要求的时间减实际睡眠时间)。
s l e e p可以用a l a r m函数(见1 0 . 1 0节)实现,但这并不是必需的。如果使用 a l a r m,则这两
个函数之间可以有交互作用。 P O S I X . 1标准对这些交互作用并未作任何说明。例如,若先调用
a l a r m ( 1 0 ),过了3秒后又调用s l e e p ( 5 ),那么将如何呢 ? sleep将在5秒后返回(假定在这段时间
内没有捕捉到另一个信号 ),但是否在 2秒后又产生另一个 S I G A L R M信号呢 ?这种细节依赖于
实现。
S V R 4用a l a r m实现s l e e p。s l e e p ( 3 )手册页中说明以前安排的闹钟仍被正常处理。
例如,在前面的例子中,在 s l e e p返回之前,它安排在 2秒后再次到达闹钟时间。
在这种情况下, s l e e p返回0。(很明显, s l e e p必须保存S I G A L R M信号处理程序的
地址,在返回前重新设置它。)另外,如果先做一次 alarm(6), 3秒钟之后又做一次
s l e e p ( 5 ),则在3秒后s l e e p返回,而不是5秒钟。此时,s l e e p的返回值则是未睡足的
时间2秒。
4 . 3 + B S D则使用另一种技术:由s e t i t i m e r ( 2 )提供间隔计时器。该计时器独立于
a l a r m函数,但在以前设置的间隔计时器和 s l e e p之间仍能有相互作用。另外,尽管
闹钟计时器 ( a l a r m )和间隔计时器 ( s e t i t i m e r )是分开的,但是不幸它们使用同一
S I G A L R M信号。因为 s l e e p暂时将该信号的处理程序改变为它自己的函数,所以
在a l a r m和s l e e p之间仍可能有不希望的相互作用。
如果混合调用s l e e p和其他与时间有关的函数,它们之间有相互作用,则你应
当清楚地了解你所使用的系统是如何实现 s l e e p的。
以前伯克利类的 s l e e p实现不提供任何有用的返回信息。这在 4 . 3 + B S D中已经
解决。
实例
程序1 0 - 2 1是一个POSIX.1 sleep函数的实现。此函数是程序 1 0 - 4的修改版,它可靠地处理
信号,避免了早期实现中的竞态条件,但是仍未处理与以前设置的闹钟的相互作用(正如前面
提到的,P O S I X . 1并未对这些交互作用进行定义)。
2 4 0 U N I X环境高级编程