欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核中信號(hào)相關(guān)的系統(tǒng)調(diào)用

jf_0tjVfeJz ? 來源:嵌入式ARM和Linux ? 2024-01-20 09:34 ? 次閱讀

正如我們所知,運(yùn)行在用戶態(tài)下的程序可以發(fā)送和接收信號(hào)。這意味著必須定義一組系統(tǒng)調(diào)用來允許這類操作。不幸的是,由于歷史原因,有些系統(tǒng)調(diào)用可能功能相同。 因此,其中一些系統(tǒng)調(diào)用永遠(yuǎn)不會(huì)被調(diào)用。例如,sys_sigaction()和sys_rt_sigaction()幾乎相同,因此C庫中包含的sigaction()包裝函數(shù)最終會(huì)調(diào)用sys_rt_sigaction()而不是sys_sigaction()。

1 kill()

kill(pid,sig)系統(tǒng)調(diào)用用來給常規(guī)進(jìn)程或多線程應(yīng)用程序發(fā)送信號(hào),相應(yīng)的服務(wù)例程是sys_kill()。pid根據(jù)值的不同具有不同意義:

pid > 0:sig信號(hào)被發(fā)送給pid指定進(jìn)程所屬的線程組。

pid = 0:sig信號(hào)被發(fā)送給與調(diào)用進(jìn)程同一進(jìn)程組內(nèi)所有進(jìn)程的線程組。

pid = –1:sig信號(hào)被發(fā)送給所有進(jìn)程,除了swapper(PID 0)、init(PID 1和current進(jìn)程。

pid < –1:信號(hào)被發(fā)送給-pid進(jìn)程組中所有進(jìn)程的所屬線程組。

sys_kill()為信號(hào)建立一個(gè)最小siginfo_t表,然后調(diào)用kill_something_info():

info.si_signo=sig;
info.si_errno=0;
info.si_code=SI_USER;
info._sifields._kill._pid=current->tgid;
info._sifields._kill._uid=current->uid;
returnkill_something_info(sig,&info,pid);

繼而,kill_something_info()既可以調(diào)用kill_proc_info()(通過group_send_sig_info()發(fā)送信號(hào)給單個(gè)線程組),也可以調(diào)用kill_pg_info()(掃描目標(biāo)進(jìn)程組所有進(jìn)程并為每個(gè)進(jìn)程調(diào)用send_sig_info()),還可以為系統(tǒng)中的每個(gè)進(jìn)程重復(fù)調(diào)用group_send_sig_info()(pid=-1)。

kill()能夠發(fā)送任何信號(hào),包括所謂的實(shí)時(shí)信號(hào)(32~64)。但是,正如我們?cè)谛盘?hào)的產(chǎn)生過程一節(jié)中看到的,kill()系統(tǒng)調(diào)用不能確保將信號(hào)添加到目標(biāo)進(jìn)程的掛起信號(hào)隊(duì)列中,因此可能會(huì)丟失多個(gè)掛起信號(hào)。實(shí)時(shí)信號(hào)應(yīng)該通過諸如rt_sigqueueinfo()之類的系統(tǒng)調(diào)用來發(fā)送。

System V和BSD Unix變體也有一個(gè)killpg()系統(tǒng)調(diào)用,它能夠顯式地向一組進(jìn)程發(fā)送信號(hào)。在Linux中,該函數(shù)是作為使用kill()系統(tǒng)調(diào)用的庫函數(shù)實(shí)現(xiàn)的。另一種變體是raise(),它向當(dāng)前進(jìn)程(即執(zhí)行函數(shù)的進(jìn)程)發(fā)送信號(hào)。在Linux中,raise()是作為庫函數(shù)實(shí)現(xiàn)的。

2 tkill()/tgkill()

tkill()和tgkill()向線程組中的特定進(jìn)程發(fā)送信號(hào)。每個(gè)兼容POSIX的pthread庫的pthread_kill()函數(shù)調(diào)用其中的一個(gè)來向特定的輕量級(jí)進(jìn)程發(fā)送信號(hào)。

tkill()需要2個(gè)參數(shù):pid,目標(biāo)進(jìn)程的PID;sig,信號(hào)編碼。內(nèi)核中的sys_tkill()服務(wù)例程填充siginfo表,獲取進(jìn)程描述符地址,進(jìn)行一些權(quán)限檢查,并調(diào)用specific_send_sig_info()發(fā)送信號(hào)。

tgkill()不同于tkill(),它需要第3個(gè)參數(shù):tgid,線程組ID,該線程組包含信號(hào)的目標(biāo)進(jìn)程。sys_tgkill()服務(wù)例程執(zhí)行與sys_tkill()完全相同的操作,但也檢查信號(hào)的目標(biāo)進(jìn)程是否屬于線程組tgid。這個(gè)額外的檢查解決了當(dāng)信號(hào)被發(fā)送到一個(gè)正在被終止的進(jìn)程時(shí)發(fā)生的競爭條件:如果另一個(gè)多線程應(yīng)用程序創(chuàng)建輕量級(jí)進(jìn)程的速度足夠快,那么信號(hào)可能會(huì)被傳遞給錯(cuò)誤的進(jìn)程。tgkill()解決了這個(gè)問題,因?yàn)榫€程組ID在多線程應(yīng)用程序的生命周期內(nèi)永遠(yuǎn)不會(huì)更改。

3 更改信號(hào)行為

sigaction(sig,act,oact)系統(tǒng)調(diào)用允許用戶為信號(hào)指定動(dòng)作;當(dāng)然,如果沒有定義信號(hào)動(dòng)作,內(nèi)核將執(zhí)行信號(hào)相關(guān)聯(lián)的默認(rèn)動(dòng)作。

相應(yīng)的sys_sigaction()服務(wù)例程作用于2個(gè)參數(shù):sig,信號(hào)值;act,類型為old_sigaction的表,用以指定新行為;oact,可選輸出參數(shù),用以獲取信號(hào)之前的行為動(dòng)作。(old_sigaction和sigaction具有相同的數(shù)據(jù)結(jié)構(gòu),但是成員順序不一致)

該函數(shù)首先檢查act地址是否有效。然后用*act的字段填充k_sigaction類型的new_ka局部變量的sa_handler、sa_flags和sa_mask字段:

__get_user(new_ka.sa.sa_handler,&act->sa_handler);
__get_user(new_ka.sa.sa_flags,&act->sa_flags);
__get_user(mask,&act->sa_mask);
siginitset(&new_ka.sa.sa_mask,mask);

函數(shù)調(diào)用do_sigaction()將新的new_ka表復(fù)制到current->sig->action表的第sig-1項(xiàng)中:

k=¤t->sig->action[sig-1];
if(act){
*k=*act;
sigdelsetmask(&k->sa.sa_mask,sigmask(SIGKILL)|sigmask(SIGSTOP));
if(k->sa.sa_handler==SIG_IGN||(k->sa.sa_handler==SIG_DFL&&
(sig==SIGCONT||sig==SIGCHLD||sig==SIGWINCH||sig==SIGURG))){
rm_from_queue(sigmask(sig),¤t->signal->shared_pending);
t=current;
do{
rm_from_queue(sigmask(sig),¤t->pending);
recalc_sigpending_tsk(t);
t=next_thread(t);
}while(t!=current);
}
}

POSIX標(biāo)準(zhǔn)要求,當(dāng)默認(rèn)動(dòng)作為ignore時(shí),將信號(hào)動(dòng)作設(shè)置為SIG_IGN或SIG_DFL會(huì)導(dǎo)致所有相同類型的掛起信號(hào)被丟棄。此外,請(qǐng)注意,無論信號(hào)處理程序請(qǐng)求的屏蔽信號(hào)是什么,SIGKILL和SIGSTOP都不會(huì)被屏蔽。

sigaction()系統(tǒng)調(diào)用還允許用戶初始化sigaction表中的sa_flags字段。我們?cè)谇懊嬖?jīng)列出了該字段允許的值和相關(guān)含義。

舊的System V Unix變體提供了signal()系統(tǒng)調(diào)用,它仍然被程序員廣泛使用。最近的C庫通過rt_sigaction()實(shí)現(xiàn)了signal()。然而,Linux仍然支持舊的C庫,并提供sys_signal()服務(wù)例程:

new_sa.sa.sa_handler=handler;
new_sa.sa.sa_flags=SA_ONESHOT|SA_NOMASK;
ret=do_sigaction(sig,&new_sa,&old_sa);
returnret?ret:(unsignedlong)old_sa.sa.sa_handler;

4 檢查掛起的阻塞信號(hào)

sigpending()系統(tǒng)調(diào)用允許進(jìn)程檢查掛起的阻塞信號(hào)集,例如那些在阻塞時(shí)產(chǎn)生的信號(hào)。對(duì)應(yīng)的sys_sigpending()服務(wù)例程作用于單個(gè)參數(shù)set,用戶變量的地址,在其中,位數(shù)組需要被拷貝:

sigorsets(&pending,¤t->pending.signal,
¤t->signal->shared_pending.signal);
sigandsets(&pending,¤t->blocked,&pending);
copy_to_user(set,&pending,4);

5 修改阻塞信號(hào)集

sigprocmask()系統(tǒng)調(diào)用允許進(jìn)程修改阻塞信號(hào)集; 它僅適用于常規(guī)(非實(shí)時(shí))信號(hào)。 相應(yīng)的sys_sigprocmask()服務(wù)例程作用于3個(gè)參數(shù):

oset: 進(jìn)程地址空間中,指向存儲(chǔ)先前位掩碼的位數(shù)組的指針。

set: 進(jìn)程地址空間中,指向存儲(chǔ)新位掩碼的位數(shù)組的指針。

how:標(biāo)志,可取的值如下所示:

SIG_BLOCK:set指向的位掩碼數(shù)組必須被添加阻塞信號(hào)的位掩碼數(shù)組中。

SIG_UNBLOCK:set指向的位掩碼數(shù)組必須從阻塞信號(hào)的位掩碼數(shù)組中移除。

SIG_SETMASK:set指向的位掩碼數(shù)組設(shè)定為新的阻塞信號(hào)的位掩碼數(shù)組。

該函數(shù)調(diào)用copy_from_user()將set指向的值拷貝到new_set這個(gè)局部變量中,并將current進(jìn)程的阻塞的標(biāo)準(zhǔn)信號(hào)的位掩碼數(shù)組拷貝到old_set這個(gè)局部變量中。然后根據(jù)how標(biāo)志設(shè)置這兩個(gè)變量:

if(copy_from_user(&new_set,set,sizeof(*set)))
return-EFAULT;
new_set&=~(sigmask(SIGKILL)|sigmask(SIGSTOP));
old_set=current->blocked.sig[0];
if(how==SIG_BLOCK)
sigaddsetmask(¤t->blocked,new_set);
elseif(how==SIG_UNBLOCK)
sigdelsetmask(¤t->blocked,new_set);
elseif(how==SIG_SETMASK)
current->blocked.sig[0]=new_set;
else
return-EINVAL;
recalc_sigpending(current);
if(oset&©_to_user(oset,&old_set,sizeof(*oset)))
return-EFAULT;
return0;

6 掛起進(jìn)程

在阻塞了由mask參數(shù)對(duì)應(yīng)的標(biāo)準(zhǔn)信號(hào)之后,sigsuspend()系統(tǒng)調(diào)用將進(jìn)程置于TASK_INTERRUPTIBLE狀態(tài)。只有當(dāng)一個(gè)非忽略、非阻塞的信號(hào)被發(fā)送給進(jìn)程時(shí),進(jìn)程才會(huì)被喚醒。

相應(yīng)的sys_sigsuspend()服務(wù)例程執(zhí)行以下內(nèi)容:

mask&=~(sigmask(SIGKILL)|sigmask(SIGSTOP));
saveset=current->blocked;
siginitset(¤t->blocked,mask);
recalc_sigpending(current);
regs->eax=-EINTR;
while(1){
current->state=TASK_INTERRUPTIBLE;
schedule();
if(do_signal(regs,&saveset))
return-EINTR;
}

將進(jìn)程設(shè)置為可中斷的掛起狀態(tài)后,調(diào)用schedule()函數(shù)選擇其它進(jìn)程來運(yùn)行。 當(dāng)發(fā)出sigsuspend()系統(tǒng)調(diào)用的進(jìn)程再次執(zhí)行時(shí),sys_sigsuspend()調(diào)用do_signal()函數(shù)來傳遞喚醒進(jìn)程的信號(hào)。 如果該函數(shù)返回值1,則不會(huì)忽略該信號(hào)。因此,系統(tǒng)調(diào)用通過返回錯(cuò)誤代碼-EINTR來終止。

其實(shí),這個(gè)功能完全可以通過組合sigprocmask()和sleep()來實(shí)現(xiàn)。但是,sigsuspend()解決了一個(gè)競態(tài)問題:因?yàn)檫M(jìn)程隨時(shí)會(huì)交叉執(zhí)行,先通過系統(tǒng)調(diào)用執(zhí)行A動(dòng)作,然后通過系統(tǒng)調(diào)用執(zhí)行B動(dòng)作,并不等價(jià)于通過單個(gè)系統(tǒng)調(diào)用直接執(zhí)行A和B兩個(gè)動(dòng)作。

這種情況下,sigprocmask()可能會(huì)在調(diào)用sleep()之前對(duì)信號(hào)解除阻塞。如果這個(gè)發(fā)生,因?yàn)閱拘研盘?hào)已經(jīng)傳遞過,從而進(jìn)程得不到喚醒而永遠(yuǎn)留在TASK_INTERRUPTIBLE狀態(tài)。相反,sigsuspend()不允許在解除阻塞之后和schedule()調(diào)用之前發(fā)送信號(hào),因?yàn)槠渌M(jìn)程在這個(gè)時(shí)間段不可能搶占CPU時(shí)間。

7 實(shí)時(shí)信號(hào)的系統(tǒng)調(diào)用

前面介紹的系統(tǒng)調(diào)用都是針對(duì)標(biāo)準(zhǔn)信號(hào)的,對(duì)于實(shí)時(shí)信號(hào)有專門的的系統(tǒng)調(diào)用。

實(shí)時(shí)信號(hào)的系統(tǒng)調(diào)用,如rt_sigaction()、rt_sigpending()、rt_sigprocmask()、rt_sigsuspend()與前面的標(biāo)準(zhǔn)信號(hào)對(duì)應(yīng)的系統(tǒng)調(diào)用類似,不再贅述。簡單介紹一下實(shí)時(shí)信號(hào)隊(duì)列相關(guān)的兩個(gè)系統(tǒng)調(diào)用:

rt_sigqueueinfo()

發(fā)送實(shí)時(shí)信號(hào),以便將其添加目標(biāo)進(jìn)程的共享掛起信號(hào)隊(duì)列中。通常通過標(biāo)準(zhǔn)庫函數(shù)中的sigqueue()實(shí)現(xiàn)。

rt_sigtimedwait()

將阻塞的掛起信號(hào)從隊(duì)列中取出而不發(fā)送它,并將信號(hào)值返回給調(diào)用者;如果沒有阻塞信號(hào)掛起,則將當(dāng)前進(jìn)程掛起一段固定的時(shí)間。通常通過標(biāo)準(zhǔn)庫函數(shù)sigwaitinfo()和sigtimedwait()調(diào)用。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1383

    瀏覽量

    40439
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11350

    瀏覽量

    210477
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    505

    瀏覽量

    19761
  • 系統(tǒng)調(diào)用

    關(guān)注

    0

    文章

    28

    瀏覽量

    8357

原文標(biāo)題:Linux內(nèi)核-信號(hào)相關(guān)的系統(tǒng)調(diào)用

文章出處:【微信號(hào):嵌入式ARM和Linux,微信公眾號(hào):嵌入式ARM和Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)核系統(tǒng)調(diào)用詳解

    Linux內(nèi)核中設(shè)置了一組用于實(shí)現(xiàn)各種系統(tǒng)功能的子程序,稱為系統(tǒng)調(diào)用。用戶可以通過系統(tǒng)
    發(fā)表于 08-23 10:37 ?822次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>中<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>詳解

    linux內(nèi)核系統(tǒng)調(diào)用之參數(shù)傳遞

    與普通函數(shù)一樣,系統(tǒng)調(diào)用通常需要一些輸入/輸出參數(shù),這些參數(shù)可能包括實(shí)際值(即數(shù)字)、用戶模式進(jìn)程地址空間中的變量地址,甚至包括指向用戶模式函數(shù)指針的數(shù)據(jù)結(jié)構(gòu)的地址(參見第11章“信號(hào)相關(guān)
    的頭像 發(fā)表于 12-20 09:32 ?1780次閱讀

    Linux內(nèi)核中信號(hào)詳解

    ? 1 信號(hào)的角色 1.1 x86/64架構(gòu)信號(hào)定義 1.2 ARM架構(gòu)信號(hào)定義 1.3 RISC-V架構(gòu)信號(hào)定義 1.4 信號(hào)
    的頭像 發(fā)表于 01-13 09:40 ?1443次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>中信號(hào)</b>詳解

    Linux內(nèi)核中信號(hào)的傳遞過程

    前面我們已經(jīng)介紹了內(nèi)核注意到信號(hào)的到來,調(diào)用相關(guān)函數(shù)更新進(jìn)程描述符以便進(jìn)程接收處理信號(hào)。但是,如果目標(biāo)進(jìn)程此時(shí)沒有運(yùn)行,
    的頭像 發(fā)表于 01-17 09:51 ?1271次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>中信號(hào)</b>的傳遞過程

    Linux內(nèi)核系統(tǒng)調(diào)用

    Linux內(nèi)核系統(tǒng)調(diào)用1. 應(yīng)用程序通過API而不是直接調(diào)用系統(tǒng)
    發(fā)表于 02-21 10:49

    ARM linux系統(tǒng)調(diào)用的實(shí)現(xiàn)原理

    大家都知道linux的應(yīng)用程序要想訪問內(nèi)核必須使用系統(tǒng)調(diào)用從而實(shí)現(xiàn)從usr模式轉(zhuǎn)到svc模式。下面咱們看看它的實(shí)現(xiàn)過程。
    發(fā)表于 05-30 11:24 ?2247次閱讀

    Linux內(nèi)核系統(tǒng)調(diào)用擴(kuò)展研究

    系統(tǒng)凋用是操作系統(tǒng)內(nèi)核提供給用戶使用內(nèi)核服務(wù)的接口。LinuX操作系統(tǒng)由于其自由開放性,用戶可在
    發(fā)表于 07-25 16:09 ?40次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>擴(kuò)展研究

    編譯Linux2.6內(nèi)核并添加一個(gè)系統(tǒng)調(diào)用

    本文以實(shí)例來詳細(xì)描述了從準(zhǔn)備一直到使用新內(nèi)核Linux2.6 內(nèi)核編譯過程,然后介紹了添加系統(tǒng)調(diào)用的實(shí)現(xiàn)步驟,最后給實(shí)驗(yàn)結(jié)果。
    發(fā)表于 12-01 15:54 ?46次下載

    透了解系統(tǒng)調(diào)用助你成為Linux下編程高手

    Linux內(nèi)核中設(shè)置了一組用于實(shí)現(xiàn)各種系統(tǒng)功能的子程序,稱為系統(tǒng)調(diào)用。用戶可以通過系統(tǒng)
    的頭像 發(fā)表于 05-11 11:27 ?3475次閱讀
    透了解<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>助你成為<b class='flag-5'>Linux</b>下編程高手

    你知道Linux系統(tǒng)調(diào)用的原理

    系統(tǒng)調(diào)用是應(yīng)用程序與操作系統(tǒng)內(nèi)核之間的接口,它決定了程序如何與內(nèi)核打交道的。無論程序是直接進(jìn)行系統(tǒng)
    發(fā)表于 05-16 16:21 ?1526次閱讀
    你知道<b class='flag-5'>Linux</b><b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>的原理

    Linux系統(tǒng)調(diào)用的技巧

    前以及大部分中斷服務(wù)返回前,都會(huì)跳轉(zhuǎn)至此處入口地址。 該段程序不僅僅為系統(tǒng)調(diào)用服務(wù),它還處理中斷嵌套、CPU調(diào)度、信號(hào)等事務(wù)?! ?.通過修改內(nèi)核源代碼添加
    發(fā)表于 04-02 14:36 ?418次閱讀

    Linux系統(tǒng)調(diào)用是什么

    所謂系統(tǒng)調(diào)用是指操作系統(tǒng)提供給用戶程序調(diào)用的一組“特殊”接口,用戶程序可以通過這組“特殊”接口獲得操作系統(tǒng)
    發(fā)表于 06-11 09:33 ?2379次閱讀

    如何區(qū)分xenomai、linux系統(tǒng)調(diào)用/服務(wù)

    對(duì)于同一個(gè)POSIX接口應(yīng)用程序,可能既需要xenomai內(nèi)核提供服務(wù)(xenomai 系統(tǒng)調(diào)用),又需要調(diào)用linux
    的頭像 發(fā)表于 05-10 10:28 ?2169次閱讀

    Linux內(nèi)核系統(tǒng)調(diào)用概述及實(shí)現(xiàn)原理

    本文介紹了系統(tǒng)調(diào)用的一些實(shí)現(xiàn)細(xì)節(jié)。首先分析了系統(tǒng)調(diào)用的意義,它們與庫函數(shù)和應(yīng)用程序接口(API)有怎樣的關(guān)系。然后,我們考察了Linux
    的頭像 發(fā)表于 05-14 14:11 ?2264次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>概述及實(shí)現(xiàn)原理

    Linux系統(tǒng)調(diào)用的具體實(shí)現(xiàn)原理

    文我將基于 ARM 體系結(jié)構(gòu)角度,從 Linux 應(yīng)用層例子到內(nèi)核系統(tǒng)調(diào)用函數(shù)的整個(gè)過程來梳理一遍,講清楚linux
    的頭像 發(fā)表于 09-05 17:16 ?1144次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>的具體實(shí)現(xiàn)原理