當前位置:首頁 » 操作系統 » linux的alarm

linux的alarm

發布時間: 2024-04-19 14:26:22

linux 的sleep()、usleep()、nanosleep()函數

原文地址: https://blog.csdn.net/weibo1230123/article/details/79139476

sleep()非系統調用,sleep()是在庫函數中實現的,它是通過alarm()來設定報警時間,使用sigsuspend()將進程掛起在信號SIGALARM上。
sleep()只能精確到秒級上。sleep()會令目前的進程暫停,直到達到參數seconds 所指定的時間,或是被信號所中斷。

return:若進程暫停到參數seconds 所指定的時間,成功則返回0,若有信號中斷則返回剩餘秒數。

除了時間單位為微秒以外,在使用上與sleep()差不多。還有就是實現也是不同的,sleep因為是用alarm實現的,所以時間單位為s ,而usleep的時間單位為us
,那肯定不是由alarm實現的,所以說它們的實現不同,但都是linux用的,而window下不能用,因為都是sleep和usleep都是在unistd.h下定義的。

return:若進程暫停到參數seconds 所指定的時間,成功則返回0,若有信號中斷則返回剩餘微秒數。

這個函數功能是暫停某個進程直到你規定的時間後恢復,參數req就是你要暫停的時間,其中req->tv_sec是以秒為單位,而tv_nsec以毫微秒為單位(10的-9次方秒)。由於調用nanosleep是是進程進入TASK_INTERRUPTIBLE,這種狀態是會相應信號而進入TASK_RUNNING狀態的,這就意味著有可能會沒有等到你規定的時間就因為其它信號而喚醒,此時函數返回-1,切還剩餘的時間會被記錄在rem中。
return: 若進程暫停到參數 req所指定的時間,成功則返回0,若有信號中斷則返回-1,並且將剩餘微秒數記錄在 rem中。

unistd.h 是 unix 系統標准頭文件,用於系統調用,相當於win32中的windows.h,unistd.h 定義的函數只能用於UNIX環境中,而不能用於windows。所以sleep 和 usleep 只能用於linux下,而不能用於windows 。
nalosleep 和 其它時間日期操作函數一樣都是定義在time.h中的,所以都適用

㈡ 關於linux中的pause()函數

這個函數是讓程序暫停,直到等到有信號到來為止。
你這段程序實際就是一直等信號。

㈢ alarm的Linux C

alarm函數
要注意的是,一個進程只能有一個鬧鍾時間,如果在調用alarm之前已設置過鬧鍾時間,則任何以前的鬧鍾時間都被新值所代替。需要注意的是,經過指定的秒數後,信號由內核產生,由於進程調度的延遲,所以進程得到控制從而能夠處理該信號還需要一些時間。
如果有以前為進程登記的尚未超時的鬧鍾時鍾,而且本次調用的seconds值是0,則取消以前的鬧鍾時鍾,其餘留值仍作為alarm函數的返回值。

㈣ linux alarm 能在線程中用嗎

不管是在進程還是線程,很多時候我們都會使用一些定時器之類的功能,這里就定時器在多線程的使用說一下。首先在linux編程中定時器函數有alarm()和setitimer(),alarm()可以提供一個基於秒的定時功能,而setitimer可以提供一個基於微妙的定時功能。

alarm()原型:
#include <unistd.h>
unsigned int alarm(unsigned int seconds);

這個函數在使用上很簡單,第一次調用這個函數的時候是設置定時器的初值,下一次調用是重新設置這個值,並會返回上一次定時的剩餘時間。

setitimer()原型:
#include <sys/time.h>
int setitimer(int which, const struct itimerval *value,struct itimerval *ovalue);

這個函數使用起來稍微有點說法,首先是第一個參數which的值,這個參數設置timer的計時策略,which有三種狀態分別是:

ITIMER_REAL:使用系統時間來計數,時間為0時發出SIGALRM信號,這種定時能夠得到一個精準的定時,當然這個定時是相對的,因為到了微秒級別我們的處理器本身就不夠精確。

ITIMER_VIRTUAL:使用進程時間也就是進程分配到的時間片的時間來計數,時間為0是發出SIGVTALRM信號,這種定時顯然不夠准確,因為系統給進程分配時間片不由我們控制。

ITIMER_PROF:上面兩種情況都能夠觸發

第二個參數參數value涉及到兩個結構體:

struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};

struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};

在結構體itimerval中it_value是定時器當前的值,it_interval是當it_value的為0後重新填充的值。而timeval結構體中的兩個變數就簡單了一個是秒一個是微秒。

上面是這兩個定時函數的說明,這個函數使用本不是很難,可以說是很簡單,但是碰到具體的應用的時候可能就遇到問題了,在多進程編程中使用一般不會碰到什麼問題,這里說的這些問題主要體現在多線程編程中。比如下面這個程序:

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

void sig_handler(int signo)
{
alarm(2);
printf("alarm signal\n");
}

void *pthread_func()
{
alarm(2);
while(1)
{
pause();
}
}

int main(int argc, char **argv)
{
pthread_t tid;
int retval;

signal(SIGALRM, sig_handler);

if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}

while(1)
{
printf("main thread\n");
sleep(10);
}
return 0;
}
這個程序的理想結果是:
main thread
alarm signal
alarm signal
alarm signal
alarm signal
alarm signal
main thread
可事實上並不是這樣的,它的結果是:
main pthread
alarm signal
main pthread
alarm signal
main pthread

為什麼會出現這種情況呢?是因為發送給工作線程的信號中斷的主線程的sleep,並且這個中情況隻影響主線程而不會影響到其他的工作線程。我們怎麼才能解決這種問題呢,最簡單的方法是修改這個程序,修改這個線程主線程使用alarm,工作線程使用sleep。這樣就能夠達到我們的要求,但是有時候有不能簡單的這樣操作。所以我們就需要進一步的修改我們的程序。在這里我第一個想到的是使用signal(SIGALRM, SIG_IGN),可是這個是設置整個進程對這個信號的響應方式,經過測試也確實不能完成我期望的功能,那麼怎麼辦呢?有這樣一個函數pthread_sigmask,線程中的信號屏蔽,函數的原型及相關函數為:

#include <signal.h>
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
函數中第一個參數how有三個值SIG_BLOCK、SIG_SETMASK和SIG_UNBLOCK這里我們是用第二個值SIG_SETMASK
int sigemptyset(sigset_t *set); /*清除信號集合set*/
int sigaddset(sigset_t *set, int signum); /*添加信號signum到信號集set中*/
然後我們改造我們的程序為:
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

void sig_handler(int signo)
{
alarm(2);
printf("alarm signal\n");
}

void *pthread_func()
{
alarm(2);
while(1)
{
pause();
}
}

int main(int argc, char **argv)
{
pthread_t tid, tid_1;
int retval;

signal(SIGALRM, sig_handler);

if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}

sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK,&sigset,NULL);

while(1)
{
printf("main pthread\n");
sleep(10);
}
return 0;
}

這個時候我們就能夠看到我們想要的結果了。

這里再附一個setitimer的使用範例:

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

struct itimerval timerval;
void sig_handler(int signo)
{
printf("alarm signal\n");
}
void *pthread_func()
{

setitimer(ITIMER_REAL, &timerval, NULL);
while(1)
{
pause();
}
}

int main(int argc, char **argv)
{
pthread_t tid;
int retval;
timerval.it_interval.tv_sec = 2;
timerval.it_interval.tv_usec = 0;
timerval.it_value.tv_sec = 2;
timerval.it_value.tv_usec = 0;

signal(SIGALRM, sig_handler);

if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}

sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK,&sigset,NULL);

while(1)
{
printf("main thread\n");
sleep(5);
}
return 0;
}

熱點內容
大宋腳本下載 發布:2024-11-27 16:21:01 瀏覽:89
sql認證培訓 發布:2024-11-27 15:53:54 瀏覽:635
php的異常處理 發布:2024-11-27 15:53:54 瀏覽:417
電腦設置郵件伺服器 發布:2024-11-27 15:53:07 瀏覽:4
安卓平板叫什麼名字 發布:2024-11-27 15:48:12 瀏覽:172
稅盤密碼忘了去改需要帶什麼 發布:2024-11-27 15:41:10 瀏覽:277
拉筋要加密 發布:2024-11-27 15:38:51 瀏覽:324
電腦當伺服器怎麼降低功耗 發布:2024-11-27 15:30:45 瀏覽:642
蘋果手機誇克緩存的視頻怎麼轉為本地視頻 發布:2024-11-27 15:24:05 瀏覽:811
linuxm4 發布:2024-11-27 15:15:12 瀏覽:322