在理解信號量之前,有2個基本概念需要整理:
一個是內核態,一個是用戶態.
用戶態好理解就是我們自己的代碼,內核態就是內核去幫我們做的事情,比如我調用了一個函數 :
memcpy();在調用的時候,就由用戶態切換到了內核態,當memcpy完成拷貝,返回的時候,就從內核態返回到了用戶態.
信號量也是同樣的道理:
當我們收到信號的時候,本質上是從內核態突然的切入到了用戶態,那麼現在問題來了。
當我們捕捉到信號量的時候,這個時候捕捉信號的方法的進程ID和線程ID和我們用戶態的主進程主線程是一樣的嗎???
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
void sigProcessINT(int signalVal)
{
std::cout << "捕捉到信號: " << signalVal << std::endl;
std::cout << "信號方法 進程id:" << getpid() << " -- 線程id:" << gettid() << std::endl;
}
int main()
{
// ctrl+c = SIGINT
// ctrl+z = SIGSTP
// 下面的命令可以追蹤進程所收到的信號,當進程退出的時候,這個命令就會退出.
//sudo strace -e trace=signal -p 5313(要追蹤的進程id)
//strace: Process 5294 attached
// --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
// +++ killed by SIGINT +++
std::cout << "信號量測試項目" << std::endl;
std::cout << "進程id:" << getpid() << " -- 線程id:" << gettid() << std::endl;
getpid();
//1. 捕捉到ctrl+c(SIGTSTP)信號 -- INT : interrupt
signal(SIGTSTP,sigProcessINT);
for(;;)
{
sleep(1);
std::cout << "休息一秒" << std::endl;
}
return 0;
}
敲黑板,這是我們的測試 demo,接下來讓我們看下 :
但是這裏大家需要萬分注意的是 :
一旦信號被觸發,當前的信號方法就會被置於前臺,以前的用戶態正在運行的方法就會被懸掛.,白話說,就是隻有被觸發的信號執行完畢了,我們原來用戶態正在運行的方法纔會繼續執行.
二:如何信號方法在運行的過程中再收到信號呢?
如果信號在運行的過程中在收到信號,那麼無論收到多少個信號,在信號方法再沒有執行完之前,所有的信號都視爲一個.