Linux--シグナル

Jan 18, 2017 am 10:28 AM

1. シグナル
シグナルは、非同期イベントが発生したことをプロセスに通知するために使用されます。カーネルは、内部イベントによりプロセスにシグナルを送信し、イベントが発生したことをプロセスに通知することもできます。シグナルは、どのようなイベントが発生したかをプロセスに通知するためにのみ使用され、プロセスにデータは渡されないことに注意してください。

**システム定義のシグナルリストを表示するには、kill-l コマンドを使用します

2. シグナルの生成方法
① キーボードのキーの組み合わせを通じてシグナルをフォアグラウンドに送信します (コマンドの後に & を追加すると、シグナルをバックグラウンドに送信できます) running)

a. SIGQUIT のデフォルトの処理アクションは、プロセスとコア ダンプを終了することです (コア ダンプはプロセスが異常終了した場合に発生します)。プロセスのユーザー空間メモリ データをディスクに保存します。これは通常、コア ダンプと呼ばれます。これは、デバッガを使用してコア ファイルを確認し、原因を見つけることができます。コア ファイルにはユーザー パスワードが含まれている可能性があり、開発中は安全ではないため、デフォルトではコア ファイルの生成は許可されません。デバッグ中に ulimit コマンドを使用してこの制限を変更し、コア ファイルを生成できるようにすることができます。
ulimit -c 1024

ulimit コマンドを使用して、シェル プロセスのリソース制限を変更します。テスト プロセスの PCB はシェル プロセスからコピーされるため、シェル プロセスと同じリソース制限値も設定されます。コアダンプが生成できることを確認します
② システム関数

aを呼び出してプロセスにシグナルを送信します。killコマンドはkill関数を呼び出すことで実装されます。 kill 関数は、指定されたシグナルを指定されたプロセスに送信できます。 raise 関数は、指定されたシグナルを現在のプロセスに送信できます (シグナルを自分自身に送信します)。 );
すべて成功した場合は 0、エラーの場合は -1 を返します。

abort 関数は、現在のプロセスを SIGABRT シグナルを受信して​​異常終了させます。
void abort(void);

exit 関数と同様に、abort 関数は常に成功するため、戻り値はありません。

③ ソフトウェア条件によって生成される信号

a.alarm 関数と SIGALRM 信号
unsigned int アラーム (unsigned int 秒) アラーム関数を呼び出すと、アラーム クロックを設定でき、カーネルに SIGALRM 信号を現在のプロセスに送信するよう指示します。 seconds 秒後、デフォルトのアクションは現在のプロセスを終了し、関数の戻り値は 0、または以前に設定されたアラーム時間の残り秒数です。
3. シグナルの扱い方
① このシグナルを無視します

② シグナルのデフォルトの処理アクションを実行し、通常はプロセスを終了します

③ シグナルの配信とブロック
①、ブロック
を実際に実行しますシグナル 処理アクションはシグナル配信 (Deliver) と呼ばれ、シグナルの生成と配信の間の状態はシグナル保留 (Pending) と呼ばれます。プロセスはシグナルをブロックすることを選択できます。ブロックされたシグナルは生成時に保留状態のままとなり、プロセスがシグナルのブロックを解除するまで配信アクションは実行されません。ブロックと無視は異なります。シグナルはブロックされている限り配信されませんが、無視は配信後のオプションの処理アクションです。
カーネル内のシグナルの表現




各シグナルには、ブロックと保留を示す 2 つのフラグ ビットと、処理アクションを示す関数ポインターがあります。シグナルが生成されると、カーネルはプロセス制御ブロック内のシグナルの保留フラグを設定します。プロセスがシグナルのブロックを解除する前にこのシグナルが複数回生成されると、シグナルが配信されるまでフラグはクリアされません。 Linux 配信前に複数回生成された場合は 1 回のみカウントされますが、配信前にリアルタイム信号が複数回生成された場合は、順番にキューに入れることができます。各信号には、0 または 1 のいずれかの保留フラグが 1 ビットだけあります。信号が生成された回数は記録されません。ブロッキング フラグもこの方法で表現されます。 (空白は状態、保留は存在または不在を示します) 保留フラグとブロッキング フラグは同じデータ型 sigset_t で保存できます。 sigset_t はシグナル セットと呼ばれ、ブロッキング シグナル セットは現在のプロセスのシグナル マスクとも呼ばれます。ここでの「シールド」は、無視するのではなく、ブロックすることとして理解されるべきです。

②、シグナルセット操作関数

#include <signal.h>
int sigemptyset(sigset_t *set);//初始化对应的信号集bit位为0
int sigfillset(sigset_t *set);//初始化对象的信号集bit位为1
int sigaddset(sigset_t *set, int signo);//添加有效信号 
int sigdelset(sigset_t *set, int signo);//删除有效信号
int sigismember(const sigset_t *set, int signo);//判断一个信号集的有效信号中是否包含某种信号,包含返回1,不包含返回0。
ログイン後にコピー
Linux--シグナル③、sigprocmask

関数sigprocmaskを呼び出して、プロセスのシグナルマスクワード(ブロッキングシグナルセット)を読み出したり、変更したりします。
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 成功した場合は 0、エラーが発生した場合は -1;
sigprocmask を呼び出すと、現在保留中のシグナルがいくつか解除される場合、sigprocmask が返される前に、シグナルの少なくとも 1 つを配信します。パラメーターの意味

SIG_BLOCK セットには現在の信号マスク ワードに追加したい信号が含まれます。

SIG_UNBLOCK セットには現在の信号マスク ワードからブロックを解除したい信号が含まれます。

SIG_SETMASK は現在の信号マスクを設定します。 word を set が指す値に変換します,

④, sigpending
int sigpending(sigset_t *set);
sigpending は、現在のプロセスの保留中のシグナルセットを読み取り、set パラメーターを通じて送信します。呼び出しが成功した場合は 0 を返し、エラーが発生した場合は -1 を返します。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
プログラムの説明

#include<stdio.h>  
  2 #include<unistd.h>  
  3 #include<signal.h>  
  4 void printsigset(sigset_t* sig)  
  5 {  
  6     int i=0;  
  7     for(;i<31;i++)  
  8     {  
  9         if(sigismember(sig,i))//判断指定信号是否在目标集合中  
 10         {  
 11             printf("1");  
 12         }  
 13         else  
 14         {  
 15             printf("0");  
 16         }  
 17     }  
 18     printf("\n");  
 19 }  
 20 int main()  
 21 {  
 22     sigset_t s,p;//定义信号集  
 23     sigemptyset(&s);//初始化  
 24     sigemptyset(&p);  
 25     sigaddset(&s,SIGINT);//设置信号ctrl+C  
 26     sigprocmask(SIG_BLOCK,&s,NULL);//设置阻塞信号集,阻塞 SIGINT信号  
 27     while(1)  
 28     {  
 29         sigpending(&p);//获取未决信号集  
 30         printsigset(&p);  
 31         sleep(1);  
 32     }  
 33     return 0;  
 34 }
ログイン後にコピー



结果分析:
程序运行时,每秒钟把各信号的未决状态打印一遍,直到按Ctrl-C将会使SIGINT信号处于未决状态,
五、捕捉信号
a.内核如何实现信号的捕捉

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号,处理过程如下,举例来说明
1. 用户程序注册了SIGQUIT信号的处理函数sighandler。
2. 当前正在执行main函数,这时发生中断或异常切换到内核态。
3. 在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。
4. 内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函 数,sighandler和main函数使用不同的堆栈空间,它们之间不存在调用和被调用的关系,是两个独立的控制流程。
5. sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。
6. 如果没有新的信号要递达,这次再返回用户态就是恢复main函数的上下文继续执行了
**(先从用户态―>内核态->返回用户态之前检查有信号递达,返回用户态处理信号->处理完成后再进入内核态->如果没有新的信号递达,返回用户态恢复上下文继续执行)
b.sigaction
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0,出错则返回- 1
将sa_handler赋值为常数SIG_IGN传给sigaction表示忽略信号,赋值为常数SIG_DFL表示执行系统默认动作,赋值为一个函数指针表示用自定义函数捕捉信号,或者说向内核注册了一个信号处理函 数,该函数返回值为void,可以带一个int参数,通过参数可以得知当前信号的编号,这样就可以用同一个函数处理多种信号。显然,这也是一个回调函数,不是被main函数调用,而是被系统所调用。
当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么它会被阻塞到当前处理结束为止。
如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。
c.pause
int pause(void);
pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause不返回;如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回-1,
用alarm和pause实现sleep(3)的函数

1 #include<stdio.h>  
 2 #include<unistd.h>  
 3 #include<signal.h>  
 4 void sig_alarm(int signo)  
 5 {  
 6        //do nothing  
 7 }  
 8 unsigned int  my_sleep(unsigned int times)  
 9 {  
 10     struct sigaction new ,old;  
 11     unsigned int unslept=0;  
 12     new.sa_handler=sig_alarm;  
 13     sigemptyset(&new.sa_mask);  
 14     sigemptyset(&old.sa_mask);  
 15     new.sa_flags=0;  
 16     sigaction(SIGALRM,&new,&old);//注册信号处理函数  
 17     alarm(times); //设置闹钟  
 18     pause();  
 19     unslept=alarm(0);//取消闹钟  
 20     sigaction(SIGALRM,&old,NULL);//恢复默认信号处理动作  
 21     return unslept;  
 22 }  
 23 int main()  
 24 {  
 25     while(1)  
 26     {  
 27         my_sleep(5);  
 28         printf("5 senconds pass\n");  
 29     }  
 30     return 0;  
 31 }
ログイン後にコピー

六、可重入函数 
当捕捉到信号时,不论进程的主控制流程当前执行到哪儿,都会先跳到信号处理函数中执行,从信号处理函数返回后再继续执行主控制流程。信号处理函数是一个单独的控制流程,因为它和主控制流程是异步的,二者不存在调用和被调用的关系,并且使用不同的堆栈空间。引入了信号处理函数使得一个进程具有多个控制流程,如果这些控制流程访问相同的全局资源(全局变量、硬件资源等),就有可能出现冲突。

以上就是Linux--信号的内容,更多相关内容请关注PHP中文网(www.php.cn)!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Deepseek Webバージョンの入り口Deepseek公式ウェブサイトの入り口 Deepseek Webバージョンの入り口Deepseek公式ウェブサイトの入り口 Feb 19, 2025 pm 04:54 PM

DeepSeekは、Webバージョンと公式Webサイトの2つのアクセス方法を提供する強力なインテリジェント検索および分析ツールです。 Webバージョンは便利で効率的であり、公式ウェブサイトは包括的な製品情報、ダウンロードリソース、サポートサービスを提供できます。個人であろうと企業ユーザーであろうと、DeepSeekを通じて大規模なデータを簡単に取得および分析して、仕事の効率を向上させ、意思決定を支援し、イノベーションを促進することができます。

DeepSeekをインストールする方法 DeepSeekをインストールする方法 Feb 19, 2025 pm 05:48 PM

DeepSeekをインストールするには、Dockerコンテナ(最も便利な場合は、互換性について心配する必要はありません)を使用して、事前コンパイルパッケージ(Windowsユーザー向け)を使用してソースからコンパイル(経験豊富な開発者向け)を含む多くの方法があります。公式文書は慎重に文書化され、不必要なトラブルを避けるために完全に準備します。

LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? Apr 01, 2025 pm 05:09 PM

LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

Bitget公式ウェブサイトのインストール(2025初心者ガイド) Bitget公式ウェブサイトのインストール(2025初心者ガイド) Feb 21, 2025 pm 08:42 PM

Bitgetは、スポット取引、契約取引、デリバティブなど、さまざまな取引サービスを提供する暗号通貨交換です。 2018年に設立されたこのExchangeは、シンガポールに本社を置き、安全で信頼性の高い取引プラットフォームをユーザーに提供することに取り組んでいます。 Bitgetは、BTC/USDT、ETH/USDT、XRP/USDTなど、さまざまな取引ペアを提供しています。さらに、この取引所はセキュリティと流動性について評判があり、プレミアム注文タイプ、レバレッジド取引、24時間年中無休のカスタマーサポートなど、さまざまな機能を提供します。

システムの再起動後にUnixSocketの権限を自動的に設定する方法は? システムの再起動後にUnixSocketの権限を自動的に設定する方法は? Mar 31, 2025 pm 11:54 PM

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

gate.ioインストールパッケージを無料で入手してください gate.ioインストールパッケージを無料で入手してください Feb 21, 2025 pm 08:21 PM

Gate.ioは、インストールパッケージをダウンロードしてデバイスにインストールすることで使用できる人気のある暗号通貨交換です。インストールパッケージを取得する手順は次のとおりです。Gate.ioの公式Webサイトにアクセスし、「ダウンロード」をクリックし、対応するオペレーティングシステム(Windows、Mac、またはLinux)を選択し、インストールパッケージをコンピューターにダウンロードします。スムーズなインストールを確保するために、インストール中に一時的にウイルス対策ソフトウェアまたはファイアウォールを一時的に無効にすることをお勧めします。完了後、ユーザーはGATE.IOアカウントを作成して使用を開始する必要があります。

OUYI OKXインストールパッケージが直接含まれています OUYI OKXインストールパッケージが直接含まれています Feb 21, 2025 pm 08:00 PM

世界をリードするデジタル資産交換であるOuyi Okxは、安全で便利な取引体験を提供するために、公式のインストールパッケージを開始しました。 OUYIのOKXインストールパッケージは、ブラウザに直接インストールでき、ユーザー向けの安定した効率的な取引プラットフォームを作成できます。インストールプロセスは、簡単で理解しやすいです。

OUYI Exchangeダウンロード公式ポータル OUYI Exchangeダウンロード公式ポータル Feb 21, 2025 pm 07:51 PM

OKXとしても知られるOUYIは、世界をリードする暗号通貨取引プラットフォームです。この記事では、OUYIの公式インストールパッケージのダウンロードポータルを提供します。これにより、ユーザーはさまざまなデバイスにOUYIクライアントをインストールすることが容易になります。このインストールパッケージは、Windows、Mac、Android、およびiOSシステムをサポートします。インストールが完了した後、ユーザーはOUYIアカウントに登録またはログインし、暗号通貨の取引を開始し、プラットフォームが提供するその他のサービスを楽しむことができます。

See all articles