MYSQL中對訊號的處理(SIGTERM,SIGQUIT,SIGHUP等)
原創,因為LINUX系統程式設計水平有限某些用詞不當請指出
一、訊號處理以及多執行緒先訊號處理基礎知識
在LINUX中訊號是一種由核心處理的一種軟中斷機制,他滿足簡單、不能攜帶大量資訊、並且要滿足一定條件才會傳送等特徵。
訊號會經歷產生-->阻塞訊號集-->未決訊號集-->訊號遞達-->訊號處理方式
首先訊號的產生可以有多種方式比如我們經常用的kill命名,下面將一些kill 中常用訊號列舉一下並且給出預設處理方式
(摘取自邢文鵬LINUX講義)
其次我們經常的按鍵也可以產生
Ctrl+c 2)SIGINT
Ctrl+\ 3)SIGQUIT
Ctrl+z 4)SIGTSTP
當然還有很多其他觸發方式比如硬體異常,raise函式,abort函式,alarm函式等等。
其次是阻塞訊號集,阻塞訊號集能夠對想除(9/19號訊號以外)的訊號進行遮蔽,如果遮蔽後訊號自然不會到達遞達狀態,也就談不上
處理了。我們透過sigprocmask函式進行阻塞訊號集的設定,但之前必須要設定sigset_t 集合,透過sigaddset sigdelset sigemptyset
sigfillset等函式設定。
未決訊號集是不能被操作的,只能被獲取透過sigpending函式獲取,但是他和阻塞訊號集一起可以控制訊號的遞達
訊號遞達後就需要處理訊號,預設的行為上面都列舉了,但是訊號(9/19號訊號以外)是可以被捕獲改變其處理方式的,我們可以自定義函式
作為某個訊號的處理方式,這可以透過signal函式和sigaction函式進行捕獲和處理,sigaction函式相對複雜需要有一個struct sigaction的
結構體變數,其中包含了sa_handler\sa_mask\sa_flags\sa_siaction 成員,這裡不做解釋可以自行檢視LINUX man page
上面是單程式下的訊號處理方式,在多執行緒下,執行緒之間公用處理方式,但是可以有不同的訊號遮蔽集,在多執行緒下一般採用設定統一的訊號
遮蔽字和訊號處理方式使用pthread_mask函式繼承到各個執行緒,同時使用sigwait/sigwaitinfo等函式設定一個單獨的訊號處理執行緒來進行統一
處理,MYSQL就是這樣處理的。
二、MYSQL中的訊號處理
首先我們可以發現MYSQL中有一個單獨的signal處理執行緒
| 36 | 1927 | sql/signal_handler | NULL | BACKGROUND | NULL | NULL |
這個執行緒對整個MYSQLD程式的訊號進行統一的處理,特別是涉及到SIGTERM,SIGQUIT,SIGHUP等訊號的處理。
下面從原始碼觸發我們來分析一下
1、訊號初始化
void my_init_signals()函式
下面我們將一些關於訊號處理的原始碼放出來進行解釋
到這裡我們發現MYSQL執行緒實際上遮蔽了SIGQUIT、SIGHUP、SIGTERM、SIGTSTP
訊號,透過一個專門的執行緒來處理這幾個訊號。同時很多訊號也重新捕獲改變了其
處理方式,詳見上面解釋。
2、訊號處理執行緒
start_signal_handler-->signal_hand 來建立訊號處理執行緒。
我們重點關注signal_hand這個回撥函式,下面是一些原始碼和解釋
這裡我們看到很多我們關心的東西:
kill/kill -15/kill -SIGTERM做什麼:
他們都是一樣的都是SIGTERM訊號MYSQL關閉所有活躍的連線同時乾淨的關閉innodb,我透過gdb確實看到了innodb關閉函式的呼叫,
這很容易我只要斷點打到innobase_shutdown_for_mysql(),同時kill mysqldpid即可
kill -3/kill -SIGQUIT做什麼:
和上面一樣,這在原始碼中清楚的看到了
kill -1/kill -SIGHUP做什麼:
原始碼解釋中說了做
reload_acl_and_cache(NULL,(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS),
NULL, ?_used); // Flush logs
函式呼叫關於引數2
@param options What should be reset/reloaded (tables, privileges, slave...)
我們可以看到這樣的解釋,那麼
REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS
代表什麼,明顯他們是點陣圖方式,他們代表的東西在原始碼中有解釋如下:
他們基本都是自解釋的,不用過多描述,那麼我們也清楚的明白了SIGHUP在mysqld中被從新定義了,做各種重新整理操作而已。
當然大家千萬不要直接kill -9這個訊號不能被遮蔽也不能被捕獲,而是強制終止程式這個時候innodb不可能呼叫
innobase_shutdown_for_mysql來乾淨的關閉MYSQLD。
作者微信:
一、訊號處理以及多執行緒先訊號處理基礎知識
在LINUX中訊號是一種由核心處理的一種軟中斷機制,他滿足簡單、不能攜帶大量資訊、並且要滿足一定條件才會傳送等特徵。
訊號會經歷產生-->阻塞訊號集-->未決訊號集-->訊號遞達-->訊號處理方式
首先訊號的產生可以有多種方式比如我們經常用的kill命名,下面將一些kill 中常用訊號列舉一下並且給出預設處理方式
(摘取自邢文鵬LINUX講義)
點選(此處)摺疊或開啟
-
1) SIGHUP:當使用者退出shell時,由該shell啟動的所有程式將收到這個訊號,預設動作為終止程式
-
2)SIGINT:當使用者按下了<Ctrl+C>組合鍵時,使用者終端向正在執行中的由該終端啟動的程式發出此訊號。預設動
-
作為終止里程。
-
3)SIGQUIT:當使用者按下<ctrl+\>組合鍵時產生該訊號,使用者終端向正在執行中的由該終端啟動的程式發出些信
-
號。預設動作為終止程式。
-
4)SIGILL:CPU檢測到某程式執行了非法指令。預設動作為終止程式併產生core檔案
-
5)SIGTRAP:該訊號由斷點指令或其他 trap指令產生。預設動作為終止里程 併產生core檔案。
-
6 ) SIGABRT:呼叫abort函式時產生該訊號。預設動作為終止程式併產生core檔案。
-
7)SIGBUS:非法訪問記憶體地址,包括記憶體對齊出錯,預設動作為終止程式併產生core檔案。
-
8)SIGFPE:在發生致命的運算錯誤時發出。不僅包括浮點運算錯誤,還包括溢位及除數為0等所有的演算法錯誤。默
-
認動作為終止程式併產生core檔案。
-
9)SIGKILL:無條件終止程式。本訊號不能被忽略,處理和阻塞。預設動作為終止程式。它向系統管理員提供了可
-
以殺死任何程式的方法。
-
10)SIGUSE1:使用者定義 的訊號。即程式設計師可以在程式中定義並使用該訊號。預設動作為終止程式。
-
11)SIGSEGV:指示程式進行了無效記憶體訪問。預設動作為終止程式併產生core檔案。
-
12)SIGUSR2:這是另外一個使用者自定義訊號 ,程式設計師可以在程式中定義 並使用該訊號。預設動作為終止程式。1
-
13)SIGPIPE:Broken pipe向一個沒有讀端的管道寫資料。預設動作為終止程式。
-
14) SIGALRM:定時器超時,超時的時間 由系統呼叫alarm設定。預設動作為終止程式。
-
15)SIGTERM:程式結束訊號,與SIGKILL不同的是,該訊號可以被阻塞和終止。通常用來要示程式正常退出。執行
-
shell命令Kill時,預設產生這個訊號。預設動作為終止程式。
-
16)SIGCHLD:子程式結束時,父程式會收到這個訊號。預設動作為忽略這個訊號。
-
17)SIGCONT:停止程式的執行。訊號不能被忽略,處理和阻塞。預設動作為終止程式。
-
18)SIGTTIN:後臺程式讀終端控制檯。預設動作為暫停程式。
-
19)SIGTSTP:停止程式的執行。按下<ctrl+z>組合鍵時發出這個訊號。預設動作為暫停程式。
-
21)SIGTTOU:該訊號類似於SIGTTIN,在後臺程式要向終端輸出資料時發生。預設動作為暫停程式。
-
22)SIGURG:套接字上有緊急資料時,向當前正在執行的程式發出些訊號,報告有緊急資料到達。如網路帶外資料
-
到達,預設動作為忽略該訊號。
-
23)SIGXFSZ:程式執行時間超過了分配給該程式的CPU時間 ,系統產生該訊號併傳送給該程式。預設動作為終止
-
程式。
-
24)SIGXFSZ:超過檔案的最大長度設定。預設動作為終止程式。
-
25)SIGVTALRM:虛擬時鐘超時時產生該訊號。類似於SIGALRM,但是該訊號只計算該程式佔用CPU的使用時間。默
-
認動作為終止程式。
-
26)SGIPROF:類似於SIGVTALRM,它不公包括該程式佔用CPU時間還包括執行系統呼叫時間。預設動作為終止進
-
程。
-
27)SIGWINCH:視窗變化大小時發出。預設動作為忽略該訊號。
-
28)SIGIO:此訊號向程式指示發出了一個非同步IO事件。預設動作為忽略。
-
29)SIGPWR:關機。預設動作為終止程式。
-
30)SIGSYS:無效的系統呼叫。預設動作為終止程式併產生core檔案。
-
31)SIGRTMIN~(64)SIGRTMAX:LINUX的實時訊號,它們沒有固定的含義(可以由使用者自定義)。所有的實時信
- 號的預設動作都為終止程式
Ctrl+c 2)SIGINT
Ctrl+\ 3)SIGQUIT
Ctrl+z 4)SIGTSTP
當然還有很多其他觸發方式比如硬體異常,raise函式,abort函式,alarm函式等等。
其次是阻塞訊號集,阻塞訊號集能夠對想除(9/19號訊號以外)的訊號進行遮蔽,如果遮蔽後訊號自然不會到達遞達狀態,也就談不上
處理了。我們透過sigprocmask函式進行阻塞訊號集的設定,但之前必須要設定sigset_t 集合,透過sigaddset sigdelset sigemptyset
sigfillset等函式設定。
未決訊號集是不能被操作的,只能被獲取透過sigpending函式獲取,但是他和阻塞訊號集一起可以控制訊號的遞達
訊號遞達後就需要處理訊號,預設的行為上面都列舉了,但是訊號(9/19號訊號以外)是可以被捕獲改變其處理方式的,我們可以自定義函式
作為某個訊號的處理方式,這可以透過signal函式和sigaction函式進行捕獲和處理,sigaction函式相對複雜需要有一個struct sigaction的
結構體變數,其中包含了sa_handler\sa_mask\sa_flags\sa_siaction 成員,這裡不做解釋可以自行檢視LINUX man page
上面是單程式下的訊號處理方式,在多執行緒下,執行緒之間公用處理方式,但是可以有不同的訊號遮蔽集,在多執行緒下一般採用設定統一的訊號
遮蔽字和訊號處理方式使用pthread_mask函式繼承到各個執行緒,同時使用sigwait/sigwaitinfo等函式設定一個單獨的訊號處理執行緒來進行統一
處理,MYSQL就是這樣處理的。
二、MYSQL中的訊號處理
首先我們可以發現MYSQL中有一個單獨的signal處理執行緒
| 36 | 1927 | sql/signal_handler | NULL | BACKGROUND | NULL | NULL |
這個執行緒對整個MYSQLD程式的訊號進行統一的處理,特別是涉及到SIGTERM,SIGQUIT,SIGHUP等訊號的處理。
下面從原始碼觸發我們來分析一下
1、訊號初始化
void my_init_signals()函式
下面我們將一些關於訊號處理的原始碼放出來進行解釋
點選(此處)摺疊或開啟
-
/*
-
SA_RESETHAND resets handler action to default when entering handler.
-
SA_NODEFER allows receiving the same signal during handler.
-
E.g. SIGABRT during our signal handler will dump core (default action).
-
*/
-
//這裡將一些列如段錯誤、浮點數例外、匯流排錯誤、CPU非法指令等訊號的預設處理
-
//方式進行修改,修改為handle_fatal_signal函式呼叫,這個函式應該是列印一些
-
//出錯時候的狀態資訊等,我沒有仔細看這個回撥函式
-
sa.sa_flags= SA_RESETHAND | SA_NODEFER;
-
sa.sa_handler= handle_fatal_signal;
-
// Treat all these as fatal and handle them.
-
(void) sigaction(SIGSEGV, &sa, NULL);
-
(void) sigaction(SIGABRT, &sa, NULL);
-
(void) sigaction(SIGBUS, &sa, NULL);
-
(void) sigaction(SIGILL, &sa, NULL);
-
(void) sigaction(SIGFPE, &sa, NULL);
-
}
-
-
// Ignore SIGPIPE and SIGALRM
-
//這裡忽略掉管道錯誤和定時器訊號
-
sa.sa_flags= 0;
-
sa.sa_handler= SIG_IGN;
-
(void) sigaction(SIGPIPE, &sa, NULL);
-
(void) sigaction(SIGALRM, &sa, NULL);
-
-
//自定義訊號,從註釋來看是終止socket通訊的
-
//回撥函式為empty_signal_handler
-
// SIGUSR1 is used to interrupt the socket listener.
-
sa.sa_handler= empty_signal_handler;
-
(void) sigaction(SIGUSR1, &sa, NULL);
-
-
-
//這裡估計是什麼特殊處理因為SIGTERM、SIGHUP已經在後面設定了
-
//阻塞,應該和平臺有關
-
// Fix signals if ignored by parents (can happen on Mac OS X).
-
sa.sa_handler= SIG_DFL;
-
(void) sigaction(SIGTERM, &sa, NULL);
-
(void) sigaction(SIGHUP, &sa, NULL);
-
-
//下面開始設定我們的阻塞訊號集透過pthread_sigmask生效
-
//要阻塞SIGQUIT、SIGHUP、SIGTERM、SIGTSTP等訊號
-
//都是一些常用的可以終止程式的訊號
-
sigset_t set;
-
(void) sigemptyset(&set);
-
/*
-
Block SIGQUIT, SIGHUP and SIGTERM.
-
The signal handler thread does sigwait() on these.
-
*/
-
(void) sigaddset(&set, SIGQUIT);
-
(void) sigaddset(&set, SIGHUP);
-
(void) sigaddset(&set, SIGTERM);
-
(void) sigaddset(&set, SIGTSTP);
-
/*
-
Block SIGINT unless debugging to prevent Ctrl+C from causing
-
unclean shutdown of the server.
-
*/
-
if (!(test_flags & TEST_SIGINT))
-
(void) sigaddset(&set, SIGINT);
-
pthread_sigmask(SIG_SETMASK, &set, NULL);
-
訊號,透過一個專門的執行緒來處理這幾個訊號。同時很多訊號也重新捕獲改變了其
處理方式,詳見上面解釋。
2、訊號處理執行緒
start_signal_handler-->signal_hand 來建立訊號處理執行緒。
我們重點關注signal_hand這個回撥函式,下面是一些原始碼和解釋
點選(此處)摺疊或開啟
-
extern "C" void *signal_hand(void *arg MY_ATTRIBUTE((unused)))
-
{
-
my_thread_init();
-
//這裡設定sigset_t訊號集合,並將SIGTERM/SIGQUIT/SIGHUP設定
-
sigset_t set;
-
(void) sigemptyset(&set);
-
(void) sigaddset(&set, SIGTERM);
-
(void) sigaddset(&set, SIGQUIT);
-
(void) sigaddset(&set, SIGHUP);
-
-
.....MUTEX相關不考慮
-
-
for (;;)
-
{
-
int sig;
-
while (sigwait(&set, &sig) == EINTR) //呼叫sigwait堵塞捕獲訊號
-
{}
-
if (cleanup_done)
-
{
-
my_thread_end();
-
my_thread_exit(0); // Safety
-
return NULL; // Avoid compiler warnings
-
}
-
switch (sig) { //下面的判斷非常重要如果是SIGTERM和SIGQUIT會
-
//pthread_kill終止所有活動的會話執行緒每個執行緒將收到
-
//SIGUSR1訊號然後呼叫empty_signal_handler回撥函式進行
-
//處理然後close_connections然後my_thread_end關閉,
-
//這裡是否呼叫innodb關閉操作,可以透過GDB打斷點
-
//到innobase_shutdown_for_mysql函式上,我做了
-
//測試確實呼叫了後面會給出,也就是說kill SIGTERM和
-
//SIGQUIT是安全的,因為他們呼叫innodb關閉函式正常
-
//的關閉了innodb
-
case SIGTERM:
-
case SIGQUIT:
-
// Switch to the file log message processing.
-
query_logger.set_handlers((log_output_options != LOG_NONE) ?
-
LOG_FILE : LOG_NONE);
-
DBUG_PRINT("info", ("Got signal: %d abort_loop: %d", sig, abort_loop));
-
if (!abort_loop)
-
{
-
abort_loop= true; // Mark abort for threads.
-
/*
-
Kill the socket listener.
-
The main thread will then set socket_listener_active= false,
-
and wait for us to finish all the cleanup below.
-
*/
-
mysql_mutex_lock(&LOCK_socket_listener_active);
-
while (socket_listener_active)
-
{
-
DBUG_PRINT("info",("Killing socket listener"));
-
if (pthread_kill(main_thread_id, SIGUSR1))
-
{
-
DBUG_ASSERT(false);
-
break;
-
}
-
mysql_cond_wait(&COND_socket_listener_active,
-
&LOCK_socket_listener_active);
-
}
-
mysql_mutex_unlock(&LOCK_socket_listener_active);
-
-
close_connections();
-
}
-
my_thread_end();
-
my_thread_exit(0);
-
return NULL; // Avoid compiler warnings
-
break;
-
case SIGHUP: //這裡也是大家很關心的關於SIGHUP到底了做了什麼
-
//我們可以看到他呼叫reload_acl_and_cache來重新整理
-
//一個東西,具體後面給出,並沒有其他什麼操作
-
//這個SIGHUP訊號的行為完全被改變了
-
if (!abort_loop)
-
{
-
int not_used;
-
mysql_print_status(); // Print some debug info
-
reload_acl_and_cache(NULL,
-
(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
-
REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS),
-
NULL, ¬_used); // Flush logs
-
// Reenable query logs after the options were reloaded.
-
query_logger.set_handlers(log_output_options);
-
}
-
break;
-
default:
-
break; /* purecov: tested */
-
}
-
}
-
return NULL; /* purecov: deadcode */
- }
這裡我們看到很多我們關心的東西:
kill/kill -15/kill -SIGTERM做什麼:
他們都是一樣的都是SIGTERM訊號MYSQL關閉所有活躍的連線同時乾淨的關閉innodb,我透過gdb確實看到了innodb關閉函式的呼叫,
這很容易我只要斷點打到innobase_shutdown_for_mysql(),同時kill mysqldpid即可
點選(此處)摺疊或開啟
-
(gdb) bt
-
#0 innobase_shutdown_for_mysql () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0start.cc:2785
-
#1 0x00000000019a0f9c in innobase_end (hton=0x2e9a450, type=HA_PANIC_CLOSE) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:4360
-
#2 0x0000000000f62215 in ha_finalize_handlerton (plugin=0x2fe31a0) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:813
-
#3 0x00000000015d3179 in plugin_deinitialize (plugin=0x2fe31a0, ref_check=true) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:995
-
#4 0x00000000015d3562 in reap_plugins () at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:1077
-
#5 0x00000000015d54c7 in plugin_shutdown () at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:1845
-
#6 0x0000000000ebf5eb in clean_up (print_message=true) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:1336
-
#7 0x0000000000ec6c7e in mysqld_main (argc=56, argv=0x2e98768) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:5358
- #8 0x0000000000ebd404 in main (argc=9, argv=0x7fffffffe418) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/main.cc:25
和上面一樣,這在原始碼中清楚的看到了
kill -1/kill -SIGHUP做什麼:
原始碼解釋中說了做
reload_acl_and_cache(NULL,(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS),
NULL, ?_used); // Flush logs
函式呼叫關於引數2
@param options What should be reset/reloaded (tables, privileges, slave...)
我們可以看到這樣的解釋,那麼
REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS
代表什麼,明顯他們是點陣圖方式,他們代表的東西在原始碼中有解釋如下:
點選(此處)摺疊或開啟
-
#define REFRESH_GRANT 1 /* Refresh grant tables */
-
#define REFRESH_LOG 2 /* Start on new log file */
-
#define REFRESH_TABLES 4 /* close all tables */
-
#define REFRESH_HOSTS 8 /* Flush host cache */
-
#define REFRESH_STATUS 16 /* Flush status variables */
-
#define REFRESH_THREADS 32 /* Flush thread cache */
-
#define REFRESH_SLAVE 64 /* Reset master info and restart slave
-
thread */
-
#define REFRESH_MASTER 128 /* Remove all bin logs in the index
-
and truncate the index */
-
#define REFRESH_ERROR_LOG 256 /* Rotate only the erorr log */
-
#define REFRESH_ENGINE_LOG 512 /* Flush all storage engine logs */
-
#define REFRESH_BINARY_LOG 1024 /* Flush the binary log */
-
#define REFRESH_RELAY_LOG 2048 /* Flush the relay log */
-
#define REFRESH_GENERAL_LOG 4096 /* Flush the general log */
- #define REFRESH_SLOW_LOG 8192 /* Flush the slow query log */
當然大家千萬不要直接kill -9這個訊號不能被遮蔽也不能被捕獲,而是強制終止程式這個時候innodb不可能呼叫
innobase_shutdown_for_mysql來乾淨的關閉MYSQLD。
作者微信:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2142060/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 處理python中的訊號Python
- MySQL:簡單記錄訊號處理MySql
- linux中的訊號處理與SROPLinux
- 科學和工程中的訊號處理
- url地址中 "&" "/"等符號的轉義處理(轉)符號
- MySQL 處理行號MySql
- 語音訊號處理入門系列(2)——訊號處理中的幾個關鍵概念音訊
- Linux訊號機制與訊號處理Linux
- 批處理中的符號符號
- 訊號處理基本引數
- linux 訊號與處理Linux
- 【scipy 基礎】--訊號處理
- 科學音訊處理(二):如何使用 Octave 對音訊檔案進行基本數學訊號處理音訊
- 訊號、系統與訊號處理邊角雜談
- Linux SIGCHLD訊號處理LinuxGC
- Linux訊號處理機制Linux
- php 處理訊號簡單演示PHP
- 細說 ReactiveCocoa 的冷訊號與熱訊號(三):怎麼處理冷訊號與熱訊號React
- Mysql RELICATION對存過的處理MySql
- 訊號處理第二篇——接著談正弦訊號
- 【js】版本號對比處理方案JS
- MySQL中的事務處理MySql
- 通訊訊號處理的一些基本常識
- Python 音訊訊號處理庫 librosaPython音訊ROS
- MATLAB及其訊號處理基礎Matlab
- Sidekiq 訊號處理原始碼分析IDE原始碼
- 大牛講解訊號與系統以及數字訊號處理
- iOS 中多音訊處理iOS音訊
- 訊號處理技術:現代通訊技術的基石
- Java中對時間的處理Java
- xenomai核心解析之訊號signal(二)---xenomai訊號處理機制AI
- 我使用過的Linux命令之trap - 在指令碼中處理訊號Linux指令碼
- Linux系統程式設計之訊號中斷處理(下)Linux程式設計
- Linux系統程式設計之訊號中斷處理(上)Linux程式設計
- 通過xml處理sql語句時對小於號與大於號的處理轉換XMLSQL
- 開心檔之C++ 訊號處理C++
- 多對一處理 和一對多處理的處理
- Mysql最佳化器對in list的處理MySql