導航:首頁 > 操作系統 > linuxsignal函數

linuxsignal函數

發布時間:2024-05-05 07:36:18

『壹』 linux 多線程編程(二)2019-08-10

三種專門用於線程同步的機制:POSIX信號量,互斥量和條件變數.

在Linux上信號量API有兩組,一組是System V IPC信號量,即PV操作,另外就是POSIX信號量,POSIX信號量的名字都是以sem_開頭.

phshared參數指定信號量的類型,若其值為0,就表示這個信號量是當前進程的局部信號量,否則該信號量可以在多個進程之間共享.value值指定信號量的初始值,一般與下面的sem_wait函數相對應.

其中比較重要的函數sem_wait函數會以原子操作的方式將信號量的值減一,如果信號量的值為零,則sem_wait將會阻塞,信號量的值可以在sem_init函數中的value初始化;sem_trywait函數是sem_wait的非阻塞版本;sem_post函數將以原子的操作對信號量加一,當信號量的值大於0時,其他正在調用sem_wait等待信號量的線程將被喚醒.
這些函數成功時返回0,失敗則返回-1並設置errno.

生產者消費者模型:
生產者對應一個信號量:sem_t procer;
消費者對應一個信號量:sem_t customer;
sem_init(&procer,2)----生產者擁有資源,可以工作;
sem_init(&customer,0)----消費者沒有資源,阻塞;

在訪問公共資源前對互斥量設置(加鎖),確保同一時間只有一個線程訪問數據,在訪問完成後再釋放(解鎖)互斥量.
互斥鎖的運行方式:串列訪問共享資源;
信號量的運行方式:並行訪問共享資源;
互斥量用pthread_mutex_t數據類型表示,在使用互斥量之前,必須使用pthread_mutex_init函數對它進行初始化,注意,使用完畢後需調用pthread_mutex_destroy.

pthread_mutex_init用於初始化互斥鎖,mutexattr用於指定互斥鎖的屬性,若為NULL,則表示默認屬性。除了用這個函數初始化互斥所外,還可以用如下方式初始化:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER。
pthread_mutex_destroy用於銷毀互斥鎖,以釋放佔用的內核資源,銷毀一個已經加鎖的互斥鎖將導致不可預期的後果。

pthread_mutex_lock以原子操作給一個互斥鎖加鎖。如果目標互斥鎖已經被加鎖,則pthread_mutex_lock則被阻塞,直到該互斥鎖佔有者把它給解鎖.
pthread_mutex_trylock和pthread_mutex_lock類似,不過它始終立即返回,而不論被操作的互斥鎖是否加鎖,是pthread_mutex_lock的非阻塞版本.當目標互斥鎖未被加鎖時,pthread_mutex_trylock進行加鎖操作;否則將返回EBUSY錯誤碼。注意:這里討論的pthread_mutex_lock和pthread_mutex_trylock是針對普通鎖而言的,對於其他類型的鎖,這兩個加鎖函數會有不同的行為.
pthread_mutex_unlock以原子操作方式給一個互斥鎖進行解鎖操作。如果此時有其他線程正在等待這個互斥鎖,則這些線程中的一個將獲得它.


三個列印機輪流列印:

輸出結果:

如果說互斥鎖是用於同步線程對共享數據的訪問的話,那麼條件變數就是用於在線程之間同步共享數據的值.條件變數提供了一種線程之間通信的機制:當某個共享數據達到某個值時,喚醒等待這個共享數據的線程.
條件變數會在條件不滿足的情況下阻塞線程.且條件變數和互斥量一起使用,允許線程以無競爭的方式等待特定的條件發生.

其中pthread_cond_broadcast函數以廣播的形式喚醒所有等待目標條件變數的線程,pthread_cond_signal函數用於喚醒一個等待目標條件變數線程.但有時候我們可能需要喚醒一個固定的線程,可以通過間接的方法實現:定義一個能夠唯一標識目標線程的全局變數,在喚醒等待條件變數的線程前先設置該變數為目標線程,然後採用廣播的方式喚醒所有等待的線程,這些線程被喚醒之後都檢查該變數以判斷是否是自己.

採用條件變數+互斥鎖實現生產者消費者模型:

運行結果:

阻塞隊列+生產者消費者

運行結果:

『貳』 linux系統上信號發送和信號接收講解

用於進程間通信,通信機制由操作系統保證,比較穩定。

在linux中可以通過kill -l查看所有信號的類型。

kill -信號類型 進程ID

int kill(pid_t pid, int sig);
入參pid :
pid > 0: 發送信號給指定的進程。
pid = 0: 發送信號給 與調用kill函數進程屬於同一進程組的所有進程。
pid < 0: 取|pid|發給對應進程組。
pid = -1:發送給進程有許可權發送的系統中所有進程。
sig :信號類型。
返回值 :成功:0;失敗:-1 (ID非法,信號非法,普通用戶殺init進程等權級問題),設置errno
以OpenHarmony源碼為例,應用ANR後,AbilityManagerService會通知應用mp堆棧信息,就是通過信號量做的。

頭文件位置 :
include <signal.h>
函數解釋 :
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
當接收到指定的信號signum時,就會跳轉到參數handler指定的函數執行。其中handler的入參是信號值。

函數原型

signum參數指出要捕獲的信號類型,act參數指定新的信號處理方式,oldact參數輸出先前信號的處理方式(如果不為NULL的話)。
sigaction結構體

sa_handler 信號處理函數
sa_mask 在處理該信號時可以暫時將sa_mask 指定的信號集擱置
sa_flags 指定一組修改信號行為的標志。 它由以下零個或多個的按位或組成
   SA_RESETHAND:當調用信號處理函數時,將信號的處理函數重置為預設值SIG_DFL
   SA_RESTART:如果信號中斷了進程的某個系統調用,則系統自動啟動該系統調用
   SA_NODEFER :一般情況下, 當信號處理函數運行時,內核將阻塞該給定信號。但是如果設置了 SA_NODEFER標記, 那麼在該信號處理函數運行時,內核將不會阻塞該信號
sa_restorer 是一個替代的信號處理程序,當設置SA_SIGINFO時才會用它。
相關函數
int sigemptyset( sigset_t *set);
sigemptyset()用來將參數set信號集初始化並清空。
執行成功則返回0,如果有錯誤則返回-1。
完整示例

『叄』 Linux 環境下的C語言, 關於 kill 發送信號和 signal() 函數, 具體問題在以下代碼的注釋處

pause()會令目前的進程暫停(進入睡眠狀態), 直到被信號(signal)所中斷。

當50信號觸動了,pause將退出睡眠狀態,執行printf和return

『肆』 linux鐨剆ignal

c璇璦signal鍑芥暟鐨勫簲鐢錛

signal鏄涓涓緋葷粺璋冪敤銆傛槸涓縐嶇壒孌婄殑涓鏂錛屽綋鏌愮嶇壒瀹氱殑鈥滆蔣浠朵腑鏂鈥濆彂鐢熸椂銆傜敤浜庤皟鐢ㄧ殑紼嬪簭銆備腑鏂閫氬父鏄紼嬪簭榪愯屼腑鍑虹幇鐨勭壒孌婃儏鍐碉紝濡傚紩鐢ㄧ壒孌婂唴瀛樹腑鐨勯潪娉曞湴鍧錛屾誕鐐規暟琚0闄ゃ

signal()鐨勫師鍨嬩負錛

#includesignal錛巋>

void(*signal(inthum錛寁oid(*func)(int)))(int)銆

signal涓鐨剗nt_鏁板強鍏跺惈涔

SIGHUP1A緇堢鎸傝搗鎴栬呮帶鍒惰繘紼嬬粓姝

SIGINT2A閿鐩樹腑鏂錛堝俠reak閿琚鎸変笅錛

SIGQU99v3C閿鐩樼殑閫鍑洪敭琚鎸変笅

SIGILL4C闈炴硶鎸囦護

SIGABRT6C鐢盿bort(3)鍙戝嚭鐨勯鍑烘寚浠

SIGFPE8C嫻鐐瑰紓甯

SIGKILL9AEFKill淇″彿

SIGSEGV11C鏃犳晥鐨勫唴瀛樺紩鐢

SIGPIPE13A綆¢亾鐮磋:鍐欎竴涓娌℃湁璇籶ort鐨勭¢亾

SIGALRM14A鐢盿larm(2)鍙戝嚭鐨勪俊鍙

SIGTERM15A緇堟淇″彿

SIGUSR130,10,16A鐢ㄦ埛鑷宸卞畾涔変俊鍙1

SIGUSR231,12,17A鐢ㄦ埛鑷宸卞畾涔変俊鍙2

SIGCHLD20,17,18B瀛愯繘紼嬬粨鏉熶俊鍙

SIGCONT19,18,25榪涚▼緇х畫錛堟浘琚鍋滄㈢殑榪涚▼錛

SIGSTOP17,19,23DEF緇堟㈣繘紼

SIGTSTP18,20,24D鎺у埗緇堢錛坱ty錛変笂鎸変笅鍋滄㈤敭

SIGTTIN21,21,26D鍚庡彴榪涚▼浼佸浘浠庢帶鍒剁粓絝璇

SIGTTOU22,22,27D鍚庡彴榪涚▼浼佸浘浠庢帶鍒剁粓絝鍐

浠ヤ笅鐨勪俊鍙鋒病鍦≒OSIX.1涓鍒楀嚭錛岃屽湪SUSv2鍒楀嚭

SIGBUS10,7,10C鎬葷嚎閿欒(閿欒鐨勫唴瀛榑闂)

SIGPOLLASysV瀹氫箟鐨凱ollable浜嬩歡錛屼笌SIGIO鍚屼箟

SIGPROF27,27,29AProfiling瀹氭椂鍣ㄥ埌

SIGSYS12,-,12C鏃犳晥鐨勭郴緇熻皟鐢(SVID)

SIGTRAP5C璺熻釜/鏂鐐規崟鑾

SIGURG16,23,21BSocket鍑虹幇緔фユ潯浠(4.2BSD)

SIGVTALRM26,26,28A瀹為檯鏃墮棿鎶ヨ︽椂閽熶俊鍙(4.2BSD)

SIGXCPU24,24,30C瓚呭嚭璁懼畾鐨凜PU鏃墮棿闄愬埗(4.2BSD)

SIGXFSZ25,25,31C瓚呭嚭璁懼畾鐨勬枃浠墮檺鍒跺ぇ灝(4.2BSD)

錛堝逛簬SIGSYS銆係IGXCPU銆係IGXFSZ銆備互鍙婃煇浜涙満鍣ㄤ綋緋葷粨鏋勪笅鐨凷IGBUS錛孡inux緙虹渷鐨勫姩浣滄槸A(terminate)錛孲USv2鏄疌(terminateandmpcore)錛夈

浠ヤ笅鏄鍏朵粬鐨勪竴浜涗俊鍙

淇″彿鍊煎勭悊鍔ㄤ綔鍙戝嚭淇″彿鐨勫師鍥

SIGIOT6CIO鎹曡幏鎸囦護錛屼笌SIGABRT鍚屼箟

SIGEMT7,-,7

SIGSTKFLT-,16,-A鍗忓勭悊鍣ㄥ爢鏍堥敊璇

SIGIO23,29,22A鏌怚/O鎿嶄綔濡備粖鑳藉熻繘琛屼簡(4.2BSD)

SIGCLD-,-,18A涓嶴IGCHLD鍚屼箟

SIGPWR29,30,19A鐢墊簮鏁呴殰(SystemV)

SIGINFO29,-,-A涓嶴IGPWR鍚屼箟

SIGLOST-,-,-A鏂囦歡閿佷涪澶

SIGWINCH28,28,20B紿椾綋澶у皬鏀瑰彉(4.3BSD,Sun)

SIGUNUSED-,31,-A鏈浣跨敤鐨勪俊鍙(willbeSIGSYS)

Linux涓嬪備綍鑾峰彇緗戝崱淇℃伅錛

鏌ョ湅linux鐨勭綉鍗′俊鎮姝ラゅ備笅錛氬伐鍏峰師鏂欙細linux鎿嶄綔緋葷粺鈶犲惎鍔╨inux鎿嶄綔緋葷粺錛岃繘鍏ュ埌妗岄潰錛

鈶″惎鍔ㄧ粓絝錛

鈶㈢粓絝杈撳叆鍛戒護ifconfigeth0錛屽洖杞︼紱鈶linux鐨勭綉鍗′俊鎮瑙h伙細

1.鏌ョ湅緗戝崱鐢熶駭鍘傚晢鍜屼俊鍙鳳細鏌ョ湅鍩烘湰淇℃伅錛歭spci鏌ョ湅璇︾粏淇℃伅錛歭spci-vvv#3涓灝忓啓鐨剉鏌ョ湅緗戝崱淇℃伅錛歭spci|grepEthernet錛

2.鏌ョ湅緗戝崱椹卞姩錛氭煡鐪嬬綉鍗¢┍鍔ㄤ俊鎮錛歭spci-vvv#鎵懼埌緗戝崱璁懼囩殑璇︾粏淇℃伅錛屽寘鎷緗戝崱椹卞姩#lsmod鍒楀嚭鍔犺澆鐨勬墍鏈夐┍鍔錛屽寘鎷緗戝崱椹卞姩錛

3.鏌ョ湅緗戝崱椹卞姩鐗堟湰鏌ョ湅妯″潡淇℃伅錛歮odifomolename>#鍏朵腑鍖呭惈version淇℃伅鎴#ethtool-idevicename>錛

4.鏌ョ湅緗戠粶鎺ュ彛闃熷垪鏁版煡鐪嬬綉鍗℃帴鍙g殑涓鏂淇℃伅錛#cat/proc/interrupts|grepeth0鎴#ethtool-Seth0錛

5.鏌ョ湅緗戝崱椹卞姩婧愮爜鐨勭増鏈鍙瘋В鍘婭ntel緗戝崱椹卞姩婧愮爜錛屾墦寮瑙e帇緙╃洰褰曚笅鐨*.spec鏂囦歡鏌ョ湅椹卞姩鐨勭増鏈錛

淇″彿he鏄鎸囦粈涔堬紵

淇″彿he鏄鎸囩殑鏄淇″彿鐨勭瘒騫呰緝灝戱紝灝辨妸浠栧拰淇″彿閲忔斁鍦ㄤ竴璧蜂簡淇″彿錛氾紙signal錛夋槸涓縐嶅勭悊寮傛ヤ簨浠剁殑鏂瑰紡銆備俊鍙鋒椂姣旇緝澶嶆潅鐨勯氫俊鏂瑰紡錛岀敤浜庨氱煡鎺ュ彈榪涚▼鏈夋煇縐嶄簨浠跺彂鐢燂紝闄や簡鐢ㄤ簬榪涚▼澶栵紝榪樺彲浠ュ彂閫佷俊鍙風粰榪涚▼鏈韜銆

linux闄や簡鏀鎸乽nix鏃╂湡鐨勪俊鍙瘋涔夊嚱鏁幫紝榪樻敮鎸佽涔夌﹀悎posix.1鏍囧噯鐨勪俊鍙峰嚱鏁

涓轟粈涔坙inux閲岀殑淇″彿鍙戦佸嚱鏁板彨kill鍛錛

鐖惰繘紼嬩細姣斿瓙榪涚▼鎻愭棭緇撴潫錛屽湪浣犲瓙榪涚▼鍙杙pid榪欎釜鏃墮棿鐖惰繘紼嬪凡緇忕粨鏉熶簡錛岃繖涓鏃跺欑浉褰撲簬瀛愯繘紼嬪彉鎴恴ombie錛屼細琚玦nit鏀跺吇錛堣繖涓鍦版柟鎴戜篃涓嶅お鎳傦紝姝e父鏉ヨ村簲璇ュ瓙榪涚▼鐨刾pid鏄1錛岃存槑浣犵殑瀛愯繘紼嬭玦nit涔嬪栫殑榪涚▼鏀跺吇浜嗭級闃誨炵埗榪涚▼鎴栬厀hile1鐨勪綔鐢ㄦ槸涓嶈╃埗榪涚▼緇撴潫錛屼互渚垮瓙榪涚▼鍙栧肩殑鏃跺欑埗榪涚▼渚濈劧淇濈暀

linux淇″彿閲忕嚎紼嬭繘紼嬪尯鍒錛

淇″彿閲忓湪榪涚▼鏄浠ユ湁鍚嶄俊鍙烽噺榪涜岄氫俊鐨勶紝鍦ㄧ嚎紼嬫槸浠ユ棤鍚嶄俊鍙瘋繘琛岄氫俊鐨勶紝鍥犱負綰跨▼linux榪樻病鏈夊疄鐜拌繘紼嬮棿鐨勯氫俊錛屾墍浠ュ湪sem_init鐨勭浜屼釜鍙傛暟瑕佷負0錛岃屼笖鍦ㄥ氱嚎紼嬮棿鐨勫悓姝ユ槸鍙浠ラ氳繃鏈夊悕淇″彿閲忎篃鍙閫氳繃鏃犲悕淇″彿錛屼絾鏄涓鑸鎯呭喌綰跨▼鐨勫悓姝ユ槸鏃犲悕淇″彿閲忥紝鏃犲悕淇″彿閲忎嬌鐢ㄧ畝鍗曪紝鑰屼笖sem_t瀛樺偍鍦ㄨ繘紼嬬┖闂翠腑錛屾湁鍚嶄俊鍙烽噺蹇呴』LINUX鍐呮牳綆$悊錛岀敱鍐呮牳緇撴瀯structipc_ids瀛樺偍錛屾槸闅忓唴鏍告寔緇鐨勶紝緋葷粺鍏抽棴錛屼俊鍙烽噺鍒欏垹闄わ紝褰撶劧涔熷彲浠ユ樉紺哄垹闄わ紝閫氳繃緋葷粺璋冪敤鍒犻櫎錛

娑堟伅闃熷垪錛屼俊鍙烽噺錛屽唴瀛樺叡浜錛岃繖鍑犱釜閮芥槸涓鏍風殑鍘熺悊銆傦紝鍙涓嶈繃淇″彿閲忓垎涓烘湁鍚嶄笌鏃犲悕

『伍』 linux c signal函數

是第二次調用的時候輸出的,第一次調用只是綁定了SIGUSR1的信號處理函數,不會進入該處理函數

為什麼會有這樣的輸出呢?
signal函數是將信號與處理函數進行綁定,成功綁定則返回綁定之前的信號處理函數。那麼來看看你的代碼,第一次調用將sig_fun1綁定,無輸出;第二次調用將sig_fun2綁定,也就是把sig_fun1替換下來,並且你還調用了它,參數為30,所以會有那樣的輸出。

該如何改呢?
其實你並沒有涉及到linux的信號處理機制,光綁定是不夠的,還需要發信號給它,才能真正進入信號處理過程。給你一個示例代碼吧
#include<signal.h>
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>

void sig_fun2(int signo)
{
printf("in sig_fun2:%d\n", signo);
}

void sig_fun1(int signo)
{
printf("in sig_fun1:%d\n", signo);
}

int main()
{
unsigned long i;
if (signal(SIGUSR1, sig_fun1) == SIG_ERR)
{
printf("signal fun1 error\n");
exit(1);
}
sleep(15);

(signal(SIGUSR1, sig_fun2))(30);
sleep(15);

printf("done\n");
return 0;
}
/****************************C 代碼完,下面是如何運行***************************/
首先編譯,假設生成可執行程序為test
然後運行,我用的是後台運行: nohup ./test>output.txt &
注意,這種方法要將輸出重定向到文件output.txt(名字無所謂),然後你會看到一個數字,就是pid進程號
最後,在15秒之內發送信號:kill -SIGUSR1 進程號
現在你就可以打開output.txt看輸出結果了。如果用sleep的話會被打斷,所以只有兩個輸出加上替換處理函數時的輸出共3個,也可以換成 int n=15;while(n--)sleep(1);
-------------------------------------------------------------
怎麼樣,加分吧
-------------------------------------------------------------
1.我就是想問第二次綁定sig_fun2的時候,調用了第一次綁定的sig_fun1么?
調用了, (signal(SIGUSR1, sig_fun2))(30);就是這一句, signal(SIGUSR1, sig_fun2)是個函數指針,你這樣寫就是調用它了,但是這和信號處理沒關系,寫成signal(SIGUSR1, sig_fun2);就可以了
這就是你所說的成功則返回綁定之前的函數???

那當時綁定sig_fun1的時候,返回之前的處理函數是什麼??
這個就是系統默認的了,比如SIGINT就是你ctrl+c取消程序執行發送的信號,它的處理函數就是結束程序的一系列動作,不過SIGUSR1是留給用戶自定義的信號,系統默認應該是啥也不做的一個函數,例如void fun(int signo){},你也可以第一次綁定的時候就調用試試看對不對

2.還有我在看signal函數定義的時候,void(//...)(int) 最後傳入的這個int整形參數就是我們自定義sig_fun()中所接收的30么??我看例子裡面有的signal(SIGINT,myfunc);也沒有帶參數啊,搞不懂
是你理解錯了,signal函數只是綁定,沒涉及到調用綁定函數,不用帶參數,信號處理函數不是像你這樣調用的。callback回調你知道吧,就是先做好一個函數或過程放著,事件觸發的時候才調用。那個30是你用普通函數調用的方式時的參數,跟信號處理一點關系也沒有,你用60,70也沒半毛錢關系。我猜你是想要調用信號處理函數,然後迷糊了,其實我上面說的「kill -SIGUSR1 進程號」就是觸發程序調用該處理函數的信號,這和kill -9 殺死進程一個道理,只不過處理函數不同,結果不一樣。ctrl+c也可以用信號的方式發送,kill -2 進程號,或者 kill -SIGINT 進程號
另外,站長團上有產品團購,便宜有保證

閱讀全文

與linuxsignal函數相關的資料

熱點內容
5995用什麼簡便演算法脫式計算 瀏覽:916
電腦上如何上小米雲伺服器地址 瀏覽:917
手機資料解壓密碼 瀏覽:442
44引腳貼片單片機有哪些 瀏覽:690
阿里程序員腦圖 瀏覽:189
廣東編程貓學習班 瀏覽:708
上海數控編程培訓學校 瀏覽:313
怎麼下載我的解壓神器 瀏覽:634
lib文件無用代碼會編譯嗎 瀏覽:28
我的世界嗨皮咳嗽伺服器怎麼下 瀏覽:1002
mvn命令順序 瀏覽:978
車貸還完多少時間解壓 瀏覽:964
java頁面開發 瀏覽:818
學編程的小發明 瀏覽:25
為什麼說程序員喜歡格子 瀏覽:253
代碼編譯後叫什麼 瀏覽:969
電腦文件夾做了保護怎麼刪除 瀏覽:678
php資料庫連接全局 瀏覽:528
葫蘆島有程序員嗎 瀏覽:986
小胖機器人顯示無命令 瀏覽:775