swoole_process原始碼分析之alarm操作
阿新 • • 發佈:2018-12-13
swoole_process提供的alarm是個高精度定時器,是作業系統setitimer
系統呼叫的封裝,可以設定微秒級別的定時器。定時器會觸發訊號,需要與swoole_process::signal
或pcntl_signal
配合使用。
function swoole_process::alarm(int $interval_usec, int $type = ITIMER_REAL) : bool
- $interval_usec 定時器間隔時間,單位為微秒。如果為負數表示清除定時器
- $type 定時器型別,0 表示為真實時間,觸發
SIGALAM
訊號,1 表示使用者態CPU時間,觸發SIGVTALAM
SIGPROF
訊號 - 設定成功返回true,失敗返回false,可以使用
swoole_errno
得到錯誤碼
下面我們分析下其流程。
static PHP_METHOD(swoole_process, alarm) { long usec = 0; long type = ITIMER_REAL; //解析輸入引數,其中usec表示定時器時間,單位為微秒;type表示定時器型別,具體參考上述php介面 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &usec, &type) == FAILURE) { return; } if (!SWOOLE_G(cli)) { swoole_php_fatal_error(E_ERROR, "cannot use swoole_process::alarm here."); RETURN_FALSE; } if (SwooleG.timer.fd != 0)//如果已經設定了其他定時事件,則不允許重複設定 { swoole_php_fatal_error(E_WARNING, "cannot use both 'timer' and 'alarm' at the same time."); RETURN_FALSE; } struct timeval now; if (gettimeofday(&now, NULL) < 0)//獲取當前時間 { swoole_php_error(E_WARNING, "gettimeofday() failed. Error: %s[%d]", strerror(errno), errno); RETURN_FALSE; } struct itimerval timer_set;//定義時間變數,這個主要用於後續的其他系統呼叫 bzero(&timer_set, sizeof(timer_set));//初始化 if (usec > 0) { long _sec = usec / 1000000; long _usec = usec - (_sec * 1000000); timer_set.it_interval.tv_sec = _sec; timer_set.it_interval.tv_usec = _usec; timer_set.it_value.tv_sec = _sec; timer_set.it_value.tv_usec = _usec; if (timer_set.it_value.tv_usec > 1e6) { timer_set.it_value.tv_usec = timer_set.it_value.tv_usec - 1e6; timer_set.it_value.tv_sec += 1; } } if (setitimer(type, &timer_set, NULL) < 0) { swoole_php_error(E_WARNING, "setitimer() failed. Error: %s[%d]", strerror(errno), errno); RETURN_FALSE; } RETURN_TRUE; }