linuxkill函數
⑴ linux 環境下的C語言, 關於 kill 發送信號和 signal() 函數, 具體問題在以下代碼的注釋處
pause()會令目前的進程暫停(進入睡眠狀態), 直到被信號(signal)所中斷。
當50信號觸動了,pause將退出睡眠狀態,執行printf和return
⑵ linux下nohup 命令怎麼kill
Unix中 nohup 命令功能就是不掛斷地運行命令,同時 nohup 把程序的所有輸出到放到當前目錄 nohup.out 文件中,如果文件不可寫,則放到 <用戶主目錄>/nohup.out 文件中。那麼有了這個命令以後我們php就寫成shell 腳本使用循環來讓我們腳本一直運行下去,不管我們終端窗口是否關閉都能夠讓我們php 腳本一直運行下去。 馬上動手寫個 PHP 小程序,功能為每30秒記錄時間,寫入到文件 復制代碼 代碼如下: # vi for_ever.php #! /usr/local/php/bin/php define('ROOT', dirname(__FILE__).'/'); set_time_limit(0); while (true) { file_put_contents(ROOT.'for_ever.txt', date('Y-m-d H:i:s')."\n", FILE_APPEND); echo date('Y-m-d H:i:s'), ' OK!'; sleep(30); } ?> 保存退出,然後賦予 for_ever.php 文件可執行許可權: # chmod +x for_ever.php 讓它在再後台執行: # nohup /home/andy/for_ever.php.php & 記得最後加上 & 符號,這樣才能夠跑到後台去運行 執行上述命令後出現如下提示: [1] 5157 nohup: appending output to 'nohup.out' 所有命令執行輸出信息都會放到 nohup.out 文件中 這時你可以打開 for_ever.php 同目錄下的 for_ever.txt 和 nohup.out 看看效果! 好了,它會永遠運行下去了,怎麼結束它呢? # ps PID TTY TIME CMD 4247 pts/1 00:00:00 bash 5157 pts/1 00:00:00 for_ever.php 5265 pts/1 00:00:00 ps # kill -9 5157 找到進程號 5157 殺之,你將看到 [1]+ Killed nohup /home/andy/for_ever.php OK! ==================== 在很多項目中,或許有很多類似的後端腳本需要通過crontab定時執行。比如每10秒檢查一下用戶狀態。腳本如下: @file: /php_scripts/scan_userstatus.php 復制代碼 代碼如下: #!/usr/bin/env php -q $status = has_goaway(); if ($status) { //done } ?> 通過crontab定時執行腳本scan_userstatus.php #echo 「*:*/10 * * * * /php_scripts/scan_userstatus.php」 這樣,每隔10秒鍾,就會執行該腳本。 我們發現,在短時間內,該腳本的內存資源還沒有釋放完,又啟用了新的腳本。也就是說:新腳本啟動了,舊腳本佔用的資源還沒有如願釋放。如此,日積月累,浪費了很多內存資源。我們對這個腳本進行了一下改進,改進後如下: @file: /php_scripts/scan_userstatus.php 復制代碼 代碼如下: #/usr/bin/env php -q while (1) { $status = has_goaway(); if ($status) { //done } usleep(10000000); } ?> 這樣,不需要crontab了。可以通過以下命令執行腳本,達到相同的功能效果 #chmod +x /php_scripts/scan_userstatus.php #nohup /php_scripts/scan_userstatus.php & 在這里,我們通過&將腳本放到後台運行,為了防止隨著終端會話窗口關閉進程被殺,我們使用了nohup命令。那麼有沒有辦法,不使nohup命令,也能夠運行呢,就像Unin/Linux Daemon一樣。接下來,就是我們要講的守護進程函數。 什麼是守護進程?一個守護進程通常補認為是一個不對終端進行控制的後台任務。它有三個很顯著的特徵:在後台運行,與啟動他的進程脫離,無須控制終端。常用的實現方式是fork() -> setsid() -> fork() 詳細如下: @file: /php_scripts/scan_userstatus.php 復制代碼 代碼如下: #/usr/bin/env php -q daemonize(); while (1) { $status = has_goaway(); if ($status) { //done } usleep(10000000); } function daemonize() { $pid = pcntl_fork(); if ($pid === -1 ) { return FALSE; } else if ($pid) { usleep(500); exit(); //exit parent } chdir("/"); umask(0); $sid = posix_setsid(); if (!$sid) { return FALSE; } $pid = pcntl_fork(); if ($pid === -1) { return FALSE; } else if ($pid) { usleep(500); exit(0); } if (defined('STDIN')) { fclose(STDIN); } if (defined('STDOUT')){ fclose(STDOUT); } if (defined('STDERR')) { fclose(STDERR); } } ?> 實現了守護進程函數以後,則可以建立一個常駐進程,所以只需要執行一次: #/php_scripts/scan_userstatus.php 這里較為關鍵的二個php函數是pcntl_fork()和posix_setsid()。fork()一個進程,則表示創建了一個運行進程的副本,副本被認為是子進程,而原始進程被認為是父進程。當fork()運行之後,則可以脫離啟動他的進程與終端控制等,也意味著父進程可以自由退出。 pcntl_fork()返回值,-1表示執行失敗,0表示在子進程中,而返進程ID號,則表示在父進程中。在這里,退出父進程。setsid(),它首先使新進程成為一個新會話的「領導者」,最後使該進程不再控制終端,這也是成為守護進程最關鍵的一步,這意味著,不會隨著終端關閉而強制退出進程。對於一個不會被中斷的常駐進程來說,這是很關鍵的一步。進行最後一次fork(),這一步不是必須的,但通常都這么做,它最大的意義是防止獲得控制終端。(在直接打開一個終端設備,而且沒有使用O_NOCTTY標志的情況下, 會獲得控制終端). 其它事項說明: 1) chdir() 將守護進程放到總是存在的目錄中,另外一個好處是,你的常駐進程不會限制你umount一個文件系統。 2)umask() 設置文件模式,創建掩碼到最大的允許限度。如果一個守護進程需要創建具有可讀,可寫許可權的文件,一個被繼承的具有更嚴格許可權的掩碼會有反作用。 3)fclose(STDIN), fclose(STDOUT), fclose(STDERR) 關閉標准I/O流。注意,如果有輸出(echo),則守護進程會失敗。所以通常將STDIN, STDOUT, STDERR重定向某個指定文件.
⑶ linux中用kill函數給init進程發送一個終止信號有什麼後果
別容易出現問題。
pid=fork();
if(pid==0)
{
子進程處理....
}
else if(pid >0)
{
父進程處理....
}
else
fork出錯處理
把你的程序改成上述形式之後,
kill完了,檢查下kill的返回值,沒有錯誤。我換了一個信號,SIGUSR1,並且給它注冊了一個簡單的信號處理函數,問題就搞定了。
SIGCONT的默認的信號處理函數不知道是什麼,但是發送SIGCONT並不能讓子進程返回,除非手動的注冊一個信號處理函數。
你試試吧。。我簡單修改的程序,好像在子進程裡面exec沒反應,但exec沒錯:
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<signal.h>
void tasksighandler(int signalnum);
void init()
{
signal(SIGUSR1,tasksighandler);
printf("task is ready ...\n");
printf("task's pid= %d\n",getpid());
pause(); //子程序掛起
printf("task's restarted...\n");
int a=0;
for(a=0;a<10;a++)
{
printf("task is diong ...\n");
sleep(1);
}
execl("/bin/ls","ls",NULL);
perror("execl");
}
void tasksighandler(int signalnum)
{
printf("OK,catch the signal\n");
}
int main()
{
int i;
pid_t pid=0;
pid=fork();
if (pid == 0) /* 子進程執行此命令 */
{
signal(SIGUSR1,tasksighandler);
printf("task is ready ...\n");
//printf("task's pid= %d\n",getpid());
pause(); //子程序掛起
printf("task's restarted...\n");
int a=0;
for(a=0;a<5;a++)
{
printf("task is diong ...\n");
sleep(1);
}
}
else if(pid > 0)
{
printf("pid is %d\n",pid);
sleep(5);
int retCode=kill(pid,SIGUSR1); //父進程給子進程發送信號,要求子進程繼續運行
if(retCode <0)
{
perror("send signal error");
}
sleep(8);
return 0;
}
else
{
perror("fork error\n");
exit(-1);
}
}
下面是關於SIGCONT的一些說明,好像你這里使用的場合並不適合:
在 POSIX-服從的平台, SIGCONT 是 信號 送到再開始a 計算機程序 由早先停留 SIGSTOP 信號。 符號常數 為SIGCONT在被定義 標頭文件 signal.h. 符號信號名字,因為信號數字可能橫跨平台,變化使用。
用法
當 SIGSTOP 在它的現狀被送到過程,通常行為是停留那個過程。 如果送它SIGCONT信號,過程只將恢復施行。 SIGSTOP和SIGCONT使用為 作業控制 在 UNIX外殼程序在其他目的中。
另外,虛機團上產品團購,超級便宜
⑷ Linux kill函數返回了1是什麼情況
返回1是沒有許可權
man 2 kill
可以查到kill函數的錯誤返回:EINVAL、EPERM和ESRCH
再看error.h里:
#define EPERM 1 /* Operation not permitted */
#define ESRCH 3 /* No such process */
#define EINVAL 22 /* Invalid argument */
⑸ linux 中 kill() 與 signal() 函數
雖然子進程將父進程的函數重新拷貝了一份,子進程和父進程共享同一段內存空間,但不能被共享。可以通過共享內存解決這個問題。使用這個函數void* mmap(void * addr, size_t len, int prot, int flags, int fd, off_t offset)把進程地址空間映射為共享內存。addr為被映射的進程地址空間內存地址,取NULL表示由系統決定;len為被映射地址空間的長度;prot為內存映射區保護參數,通常取為PROT_READ|PROT_WRITE;flags為標志,通常取為MAP_SHARED|MAP_ANON;fd取為-1,offset取為0。成功返回被映射區的起始地址,失敗返回錯誤碼。需要的頭文件為:sys/mman.h。
使用方法:int * share; //假設要把share所指向的一個整型變數映射為共享內存空間。
share = (int *)mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0 )這樣就能實現你說的 了.
⑹ unix,linux環境編程中關於signal函數和kill函數問題
signal函數調用後會進入系統的信號隊列,具體什麼時候執行是不可控的。
⑺ Linux的kill函數和SIGUSR1信號。
對於這個信號而言,沒有信號響應函數的話,進程應該會異常終止,對於系統已有的信號一般都是有默認處理的,具體的我有點記不得了,搜下其實就知道了.我在網上找了下各信號默認處理方式,你看看吧,對你有沒有用
信號名稱 信號說明 默認處理
SIGABRT 由程序調用 abort時產生該信號。 程序異常結束。 進程終止並且產生core文件
SIGALRM timer到期, 有alarm或者setitimer 進程終止
SIGBUS 匯流排錯誤,地址沒對齊等。取決於具體硬體。 結束終止並產生core文件
SIGCHLD 進程停止或者終止時,父進程會收到該信號。 忽略該信號
SIGCONT 讓停止的進程繼續執行 繼續執行或者忽略
SIGFPE 算術運算異常,除0等。 進程終止並且產生core文件。
SIGHUP 終端關閉時產生這個信號 進程終止
SIGILL 代碼中有非法指令 進程終止並產生core文件
SIGINT 終端輸入了中斷字元ctrl+c 進程終止
SIGIO 非同步I/O,跟SIGPOLL一樣。 進程終止
SIGIOT 執行I/O時產生硬體錯誤 進程終止並且產生core文件
SIGKILL 這個信號用戶不能去捕捉它。 進程終止
SIGPIPE 往管道寫時,讀者已經不在了,或者往一個已斷開數據流socket寫數據。 進程終止
SIGPOLL 非同步I/O,跟SIGIO一樣。 進程終止
SIGPROF 有setitimer設置的timer到期引發 。 進程終止
SIGPWR Ups電源切換時 進程終止
SIGQUIT Ctrl+\,不同於SIGINT,這個是會產生core mp文件的。 進程終止並且產生core文件
SIGSEGV 內存非法訪問,默認列印出segment fault 進程終止並且產生core文件
SIGSTOP 某個進程停止執行,該信號不能被用戶捕捉。 進程暫停執行
SIGSYS 調用操作系統不認識的系統調用。 進程終止並且產生core文件
SIGTERM 有kill函數調用產生。 進程終止
SIGTRAP 有調試器使用,gdb 進程終止並且產生core文件
SIGTSTP Ctrl+z,掛起進程。 進程暫停
SIGTTIN 後台程序要從終端讀取成數據時。 進程暫停
SIGTTOU 後台終端要把數據寫到終端時。 進程暫停
SIGURG 一些緊急的事件,比如從網路收到帶外數據。 忽略
SIGUSR1 用戶自定義信號 進程終止
SIGUSR2 用戶自定義信號 進程終止
SIGVTALRM 有setitimer產生。 進程終止
⑻ Linux中的kill與kill -9
1、我們經常會用到kill命令去殺死一個進程,但是有時會出現kill不成功山帆塵的現象,這是就要用到kill -9。
2、之所以這兩個命令會有區別是因為所發送的 信號(Signal) 是不同的:
默認情況下kill命令的參數為-15,如下逗禪圖所示:
kill -15代表的信號為SIGTERM,這是告訴進程你 需要被關閉,請自行轎悉停止運行並退出 ;
而kill -9代表的信號是SIGKILL,表示進程被終止,需要 立即退出 ;
3、因此kill -9表示強制殺死該進程,這個信號 不能被捕獲也不能被忽略 。
⑼ Linux C函數Kill
你是程序中調用kill函數,還是在命令行調用kill命令?
int kill(pid_t pid, int sig); 函數有兩個參數,一個是進程號,一個是信號
如果你輸入的進程號是正確的,而進程還在,則信號有可能被該進程忽略了,不知道你發送的信號是幾號? 只有SIGKILL SIGSTOP不能被忽略,其它都可以忽略或捕捉。