日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 信号可靠性,同步,异步,多线程信号等介绍

發布時間:2024/10/12 linux 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 信号可靠性,同步,异步,多线程信号等介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鑒于網上超多關于Linux信號處理相關的文章,本篇關于基本的信號知識不再普及,只提出一些平時不常關注或者關注不到的一些方面:

1. 信號可靠性:此可靠指的是信號是否會排隊,并不是指信號會丟失(其實在也可以理解為不排隊的信號就會丟失)。SIGRTMIN以下的信號不會被排隊處理,即只傳遞一次,如果進程已經有信號還未被處理,后面再來同樣的信號即丟失,其他的不同信號還是進入排隊處理。SIGRTMIN以上的信號,都會進入隊列

2. 信號異步處理:進程注冊的信號處理函數將在進程內核態返回用戶態時被調用,相對于進程主線程或其他線程來說,是并行處理的

3. 信號同步處理:進程可以選擇以同步的方式來處理信號,比如由一個特定的線程來處理

4. 多線程中的信號:對于內核來說,沒有進程與線程的區分,所有都是進程;對于進程來說,所有線程共享進程地址空間,包括注冊的信號,即子線程會繼承主線程所注冊的信號環境

5. 誰來執行信號處理函數:異步處理時由最小號的線程來處理;同步處理時由用戶特定的調用同步函數的線程來執行

6. 誰可以注冊信號:誰都可以注冊,主線程子線程都可以;注冊與處理不是相關聯的

7. 在多個地方注冊信號了處理函數,將怎么處理:信號處理函數將以最后調用的信號注冊函數為準

關于信號API:

異步處理 sigaction:

void sig_handler(int signum) {... }struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = sig_handler; sigemptyset(&action.sa_mask); action.sa_flags = 0; /* restart property */ action.sa_flags |= SA_RESTART; sigaction(SIGUSR2, &action, NULL);

同步處理 sigwaitinfo:

void* sub_sig_handle_thread() {sigset_t waitset, oset;siginfo_t info;int rc;pthread_t ppid = pthread_self();pthread_detach(ppid);sigemptyset(&waitset);sigaddset(&waitset, SIGRTMIN);sigaddset(&waitset, SIGUSR1);while (1) {rc = sigwaitinfo(&waitset, &info);if (rc != -1) {printf("<--sigwaitinfo() fetch the signal %d\n", rc);sig_handler(info.si_signo);} else {printf("<--sigwaitinfo() return err: %d; %s\n", errno, strerror(errno));}} }

在某個獨立的線程中,循環調用sigwaitinfo檢測是否有未處理的信號,有則主動調用信號處理函數

多線程信號繼承:

1. 每個線程都有自己獨立的signal mask,但所有線程共享進程的signal action

2. 主線程調用pthread_sigmask創建信號屏蔽策略,將被所有子線程繼承

3. pthread_kill 發送的目的線程需要與調用線程再同一個進程之中

4. 跨進程發送信號使用kill 指定進程PID

5. 同步處理時,子線程sigaddset的信號必須是主線程sigaddset的子集

同步、異步處理共存:

1. 同樣的信號同時都被同步異步所注冊,同步優先級更高,將以同步方式處理

2. 不同信號可以被不同方式處理,比如同步處理SIGUSR1的同時可以異步處理SIGUSR2

測試例程:

#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <pthread.h> #include <unistd.h> #include <sys/types.h>#define MUTIL_THREAD 1void sig_handler(int signum) {static int j = 0;static int k = 0;pthread_t sig_ppid = pthread_self(); // used to show which thread the signal is handled in.printf("<-- get sig %d\n", signum);if (signum == SIGUSR1) {printf("<--thread %ld, receive SIGUSR1 No. %d\n", sig_ppid, j);j++;//SIGRTMIN should not be considered constants from userland, //there is compile error when use switch case} else if (signum == SIGRTMIN) {printf("<--thread %ld, receive SIGRTMIN No. %d\n", sig_ppid, k);k++;} else if (signum == SIGUSR2) {printf("<--thread %ld, receive SIGUSR2\n", sig_ppid);} }void* worker_thread() {pthread_t ppid = pthread_self();pthread_detach(ppid);int ret = 0;struct timeval tv = {10, 0}; //10swhile (1) {printf("I'm thread %ld, I'm alive\n", ppid);tv.tv_sec = 10;ret = select(0, NULL, NULL, NULL, &tv);if(ret < 0)printf("thread %ld interrupt by signal\n", ppid);//sleep(10);} }void* sigmgr_thread() {sigset_t waitset, oset;siginfo_t info;int rc;pthread_t ppid = pthread_self();pthread_detach(ppid);#if MUTIL_THREADsigemptyset(&waitset);sigaddset(&waitset, SIGRTMIN);sigaddset(&waitset, SIGUSR1); #elsestruct sigaction action;memset(&action, 0, sizeof(action)); action.sa_handler = sig_handler;sigemptyset(&action.sa_mask);action.sa_flags = 0;/* restart property */action.sa_flags |= SA_RESTART;sigaction(SIGUSR2, &action, NULL); #endifwhile (1) {rc = sigwaitinfo(&waitset, &info);if (rc != -1) {printf("<--sigwaitinfo() fetch the signal %d\n", rc);sig_handler(info.si_signo);} else {printf("<--sigwaitinfo() return err: %d; %s\n", errno, strerror(errno));}} }int main() {sigset_t bset, oset;int i;pid_t pid = getpid();pthread_t ppid[7];struct sigaction action;memset(&action, 0, sizeof(action)); action.sa_handler = sig_handler;sigemptyset(&action.sa_mask);action.sa_flags = 0;/* restart property */action.sa_flags |= SA_RESTART;#if MUTIL_THREADsigaddset(&action.sa_mask, SIGRTMIN);sigaddset(&action.sa_mask, SIGUSR1); //handle by sub-thread // sigaddset(&action.sa_mask, SIGUSR2);if(pthread_sigmask(SIG_BLOCK, &action.sa_mask, &oset) != 0)printf("!! Set pthread mask failed\n");sigaction(SIGUSR2, &action, NULL); //handle by main #elsesigaction(SIGUSR1, &action, NULL);sigaction(SIGRTMIN, &action, NULL); //only main #endifprintf("main pid %d, %ld\n", pid, pthread_self());// Create the dedicated thread sigmgr_thread() which will handle // SIGUSR1 and SIGRTMIN synchronouslypthread_create(&ppid[0], NULL, sigmgr_thread, NULL);// Create 5 worker threads, which will inherit the thread mask of// the creator main threadfor (i = 0; i < 5; i++) {pthread_create(&ppid[i+1], NULL, worker_thread, NULL);}//wait sub-thread to regist signalsleep(3);// send out 50 SIGUSR1 and SIGRTMIN signalsfor (i = 0; i < 5; i++) {printf("\n-->main thread, send SIGUSR1 No. %d\n", i);kill(pid, SIGUSR1);printf("-->main thread, send SIGRTMIN No. %d\n", i);kill(pid, SIGRTMIN);printf("-->main thread, send SIGUSR2 No. %d\n", i);kill(pid, SIGUSR2);sleep(1);}struct timeval tv = {50, 0};int ret = select(0, NULL, NULL, NULL, &tv);if(ret < 0)printf("main interrupt by signal\n");return 0; }

運行結果:

main pid 12018, 140114995099392
I'm thread 140114978449152, I'm alive
I'm thread 140114970056448, I'm alive
I'm thread 140114953271040, I'm alive
I'm thread 140114944878336, I'm alive
I'm thread 140114961663744, I'm alive

-->main thread, send SIGUSR1 No. 0
-->main thread, send SIGRTMIN No. 0
-->main thread, send SIGUSR2 No. 0
<-- get sig 12
<--thread 140114995099392, receive SIGUSR2??? --->主線程處理USR2
<--sigwaitinfo() fetch the signal 10
<-- get sig 10
<--thread 140114986841856, receive SIGUSR1 No. 0?? -->同步處理信號
<--sigwaitinfo() fetch the signal 34
<-- get sig 34
<--thread 140114986841856, receive SIGRTMIN No. 0?? -->同步處理信號

-->main thread, send SIGUSR1 No. 1
-->main thread, send SIGRTMIN No. 1
-->main thread, send SIGUSR2 No. 1
<--sigwaitinfo() fetch the signal 10
<-- get sig 10
<--thread 140114986841856, receive SIGUSR1 No. 1
<--sigwaitinfo() fetch the signal 34
<-- get sig 34
<--thread 140114986841856, receive SIGRTMIN No. 1
<-- get sig 12
<--thread 140114995099392, receive SIGUSR2

總結

以上是生活随笔為你收集整理的Linux 信号可靠性,同步,异步,多线程信号等介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 性猛交富婆╳xxx乱大交天津 | 久久视频黄色 | 神马香蕉久久 | 欧美理论视频 | 少妇野外性xx老女人野外性xx | 狠狠搞视频 | 成人精品国产 | av男女 | 免费观看黄色的网站 | 第一页在线| 野外(巨肉高h) | 五月天婷婷久久 | 久久99久久99精品免视看婷婷 | 69国产在线 | 日本美女a级片 | 欧美日韩在线免费看 | 日日影院 | 亚洲国产欧洲 | 久久欲 | 69视频免费看 | 一区二区三区四区五区六区 | 天天射天天射天天射 | 今天最新中文字幕mv高清 | 96亚洲精品久久久蜜桃 | 无遮挡的裸体按摩的视频 | 在线观看免费的av | 日韩不卡av在线 | 成人手机av| 成人97 | 欧美激情黄色 | 成人观看 | 国产综合图区 | 在线观看91视频 | 亚洲天堂免费在线观看视频 | 亚洲色图导航 | 强乱中文字幕av一区乱码 | 国产高潮失禁喷水爽到抽搐 | 成人久久久精品乱码一区二区三区 | 99ri在线观看| 91精品视频一区 | 欧美成人精品 | 麻豆av在线免费观看 | 欧美综合第一页 | 久草成人 | xxxxx黄色片 噜噜噜噜噜色 | 香蕉视频在线观看免费 | 国产黄色网页 | 91在线第一页 | 性久久久久久久久久久 | 免费看日批 | 成人h动漫精品一区二区下载 | 国产精品99久久久久久久久 | 成人免费aaa| 一区二区三区四区不卡 | 欧美1级片 | 91美女福利视频 | 97精品人妻一区二区三区蜜桃 | 黄色录像一级大片 | 国产一区二区片 | 精品国产一二 | 亚洲综合婷婷 | 狠狠躁夜夜躁人 | 一区二区三区精品在线 | 草逼视频免费看 | 久久久久亚洲精品中文字幕 | 亚洲一区二区三区久久久 | 日韩综合 | 国产午夜伦鲁鲁 | www.jizzcom| 色花堂在线 | jizz韩国| 激情综合五月婷婷 | 亚洲国产成人精品激情在线 | 91免费视频入口 | 国产精品久久久久久久久免费看 | 不卡一区在线 | 国产欧美日韩综合精品一区二区三区 | 成人免费性视频 | 国产又粗又猛又黄又爽视频 | 精品在线视频一区 | 神马久久网 | 久久视频热 | 天海翼一区 | 善良的公与媳hd中文字 | 久久综合精品国产二区无码不卡 | 东方av在线免费观看 | 操你啦影院 | 一区二区三区在线观看视频 | 婷婷射图 | 一进一出好爽视频 | 色婷婷视频在线观看 | 一区二区三区爱爱 | 久久精品久久久精品美女 | 亚洲大尺度在线 | 午夜欧美精品久久久久久久 | 99视频久久| 日韩不卡在线视频 | 亚洲第一天堂影院 | 日本一级淫片免费放 |