桃園蘆竹五酒桶山O型 A10機捷山鼻站
桃園蘆竹區的五酒桶山,海拔170公尺,是個踏青的好地方.
搭機捷到A10山鼻站 出站 (2025.08.31 11:53) 大熱天,全程撐傘走完O型路線,大約花費2個小時30分鐘...

lyt0112 發表在 痞客邦 留言(0) 人氣()

Class B Subnet Blocks
 /20 -- 16*/24 Subnets 

lyt0112 發表在 痞客邦 留言(0) 人氣()

P_20160911_173416.jpg
日光溫泉會館-花見西餐廳下午茶
早上到新開幕的台中歌劇院晃晃...晃完沿著文心路騎接東山路過東東芋圓後沒多久,會看到一台彩繪飛機...那是"橋王花園酒店"

lyt0112 發表在 痞客邦 留言(0) 人氣()

DSC_5499.jpg
炎炎夏日,懶懶的2個人摸到中午才想著出遊....
吃完午餐後出發來去進昌咖啡烘焙館吃下午茶...

lyt0112 發表在 痞客邦 留言(0) 人氣()

黃金博物館園區很大,包含 四連棟、太子賓館、神社遺址 ...等,可以悠閒慢慢逛,慢慢拍照...
 
瑞芳搭公車(一段票)直接搭到黃金博物館門口下車
DSC_4768.jpg

lyt0112 發表在 痞客邦 留言(0) 人氣()

DSC_1123.jpg
往年常聽到泰安有落羽松,今年想到來去看看...
但時間太晚了,出發前想說應該掉光光了吧...
賭看看還能不能看的到囉...
於是和女友,直接搭火車到泰安火車站...
出站後往右走,走1-2分鐘會到一個十字叉路...

lyt0112 發表在 痞客邦 留言(0) 人氣()

新版本 gcc 編譯包含 __DATE__ 或者 __TIME__ 程式碼時,可能會報下面的錯誤:
error: macro "__DATE__" might prevent reproducible builds
error: macro "__TIME__" might prevent reproducible builds

lyt0112 發表在 痞客邦 留言(0) 人氣()

重點:
系統不能啟動

lyt0112 發表在 痞客邦 留言(0) 人氣()


iptables是在linux內核裡配置防火牆規則的用戶空間工具,它實際上是netfilter框架的一部分.可能因為iptables是netfilter框架裡最常見的部分,所以這個框架通常被稱為iptables,iptables是linux從2.4版本引入的防火牆解決方案.
ipset是iptables的擴展,它允許你創建 匹配整個地址sets(地址集合) 的規則。而不像普通的iptables鏈是線性的存儲和過濾,ip集合存儲在帶索引的數據結構中,這種結構即時集合比較大也可以進行高效的查找.
除了一些常用的情況,比如阻止一些危險主機訪問本機,從而減少系統資源佔用或網絡擁塞,IPsets也具備一些新防火牆設計方法,並簡化了配置.
在本文中,在快速的討論ipsets的安裝要求後,我會花一點時間來介紹iptables的核心機制和基本概念.然後我會介紹ipset的使用方法和語法,並且演示ipset如何與iptables結合來完成各種不同的配置。最後,我會提供一些細節和較高級的例子來演示如何解決現實中的問題。
ipset比傳統的iptables擁有顯著的性能提升和擴展特性,比如將單個防火牆規則通過一次配置應用到整個主機所在的組和網絡。
由於ipset只是iptables的擴展,所以也會對iptables進行描述。
在許多的linux發佈中ipset是一個簡單的安裝包,大家可以通過自己的linux發行版提供的包管理工具進行安裝。
需要理解的重點時,同iptables一樣,ipset是由用戶空間的工具和內核空間的模塊兩部分組成,所以你需要將這兩部分都準備好。你也需要"ipset-aware"這個iptables 模塊,這個模塊用來增加 rules that match against sets。(……)
首先我們使用自己的linux發行版的包管理工具對ipset進行搜索。在ubuntu上安裝需要安裝ipset 和 xtables-addons-source 包,然後,運行module-assistant auto-install xtables-addons,等待大約30秒後ipset就可以使用了。
如果你的linux發行版沒有被支持,那就需要根據ipset 首頁中的安裝步驟構建源碼並對內核打補丁。
這篇文章中使用ipset v4.3 和 iptables v1.4.9。
iptables概述
簡單來講,iptables防火牆配置由規則鏈的集合組成,每一個鏈包含一個規則。一個數據包,在各個處理階段,內核商量合適的規則來決定數據報的命運。
規則鏈按照順序進行匹配,基於數據包的流向 (remote-to-local, remote-to-remote or local-to-remote)和當前所處的處理階段(before or after "routing")。參考圖1。

lyt0112 發表在 痞客邦 留言(0) 人氣()

使用 iptables 封 IP,是一種比較簡單的應對網絡攻擊的方式,也算是比較常見。有時候可能會封禁成千上萬個 IP,如果添加成千上萬條規則,在一台注重性能的服務器或者本身性能就很差的設備上,這就是個問題了。ipset 就是為了避免這個問題而生的。


關於 iptables,要知道這兩點。



  • iptables 包含幾個表,每個表由鏈組成。默認的是 filter 表,最常用的也是 filter 表,另一個比較常用的是 nat 表。一般封 IP 就是在 filter 表的 INPUT 鏈添加規則。

  • 在進行規則匹配時,是從規則列表中從頭到尾一條一條進行匹配。


這像是在鏈表中搜索指定節點費力。ipset 提供了把這個 O(n) 的操作變成 O(1) 的方法:就是把要處理的 IP 放進一個集合,對這個集合設置一條 iptables 規則。像 iptable 一樣,IP sets 是 Linux 內核中的東西,ipset 這個命令是對它進行操作的一個工具。


簡單的流程


可以用這幾條命令概括使用 ipset 和 iptables 進行 IP 封禁的流程


ipset create vader hash:ip 
iptables -I INPUT -m set --match-set vader src -j DROP
ipset add vader 4.5.6.7
ipset add vader 1.2.3.4
ipset add vader ...
ipset list vader # 查看 vader 集合的內容

下面分別對各條命令進行描述。


創建一個集合


ipset create vader hash:ip 

這條命令創建了名為 vader 的集合,以 hash 方式存儲,存儲內容是 IP 地址。


添加 iptables 規則


iptables -I INPUT -m set --match-set vader src -j DROP 

如果源地址(src)屬於 vader 這個集合,就進行 DROP 操作。這條命令中,vader 是作為黑名單的,如果要把某個集合作為白名單,添加一個 『!』 符號就可以。


iptables -I INPUT -m set ! --match-set yoda src -j DROP 

到現在雖然創建了集合,添加了過濾規則,但是現在集合還是空的,需要往集合裡加內容。


找出「壞」 IP


找出要封禁的 IP,這是封禁過程中重要的步驟,不過不是這裡的重點。簡要說明一下兩種方法思路。


netstat -ntu | tail -n +3 | awk '{print $5}' | sort | uniq -c | sort -nr 

直接通過 netstat 的信息,把與本地相關的各種狀態的 IP 都計數,排序列出來。


或者從 nginx 或者其他 web server 的日誌裡找請求數太多的 IP


awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr 

後半部分,排序,去重,再按次數進行逆向排序的操作,跟上面命令是一樣的。


找出「壞」 IP,往之前創建的集合裡添加就可以了。


ipset add vader 4.5.6.7 

有多少「壞」 IP,就添加多少 IP,因為針對這些封禁的 IP 只需要一條 iptables 規則,而這些 IP 是以 hash 方式存儲,所以封禁大量的 IP 也不會影響性能,這也是 ipset 存在的最大目的。


 


ipset 更多的用法


存儲類型


前面例子中的 vader 這個集合是以 hash 方式存儲 IP 地址,也就是以 IP 地址為 hash 的鍵。除了 IP 地址,還可以是網絡段,端口號(支持指定 TCP/UDP 協議),mac 地址,網絡接口名稱,或者上述各種類型的組合。


比如指定 hash:ip,port就是 IP 地址和端口號共同作為 hash 的鍵。查看 ipset 的幫助文檔可以看到它支持的所有類型。


下面以兩個例子說明。


hash:net


ipset create r2d2 hash:net 
ipset add r2d2 1.2.3.0/24
ipset add r2d2 1.2.3.0/30 nomatch
ipset add r2d2 6.7.8.9
ipset test r2d2 1.2.3.2

hash:net 指定了可以往 r2d2 這個集合裡添加 IP 段或 IP 地址。


第三條命令裡的 nomatch 的作用簡單來說是把 1.2.3.0/301.2.3.0/24 這一範圍相對更大的段裡「剝離」了出來,也就是說執行完 ipset add r2d2 1.2.3.0/24 只後1.2.3.0/24 這一段 IP 是屬於 r2d2 集合的,執行了 ipset add r2d2 1.2.3.0/30 nomatch 之後,1.2.3.0/24 裡 1.2.3.0/30 這部分,就不屬於 r2d2 集合了。執行 ipset test r2d2 1.2.3.2 就會得到結果 1.2.3.2 is NOT in set r2d2.


hash:ip,port


ipset create c-3po hash:ip,port 
ipset add c-3po 3.4.5.6,80
ipset add c-3po 5.6.7.8,udp:53
ipset add c-3po 1.2.3.4,80-86

第二條命令添加的是 IP 地址為 3.4.5.6,端口號是 80 的項。沒有註明協議,默認就是 TCP,下面一條命令則是指明了是 UDP 的 53 端口。最後一條命令指明了一個 IP 地址和一個端口號範圍,這也是合法的命令。


自動過期,解封


ipset 支持 timeout 參數,這就意味著,如果一個集合是作為黑名單使用,通過 timeout 參數,就可以到期自動從黑名單裡刪除內容。


ipset create obiwan hash:ip timeout 300 
ipset add obiwan 1.2.3.4
ipset add obiwan 6.6.6.6 timeout 60

上面第一條命令創建了名為 obiwan 的集合,後面多加了 timeout 參數,值為 300,往集合裡添加條目的默認 timeout 時間就是 300。第三條命令在向集合添加 IP 時指定了一個不同於默認值的 timeout 值 60,那麼這一條就會在 60 秒後自動刪除。


隔幾秒執行一次 ipset list obiwan 可以看到這個集合裡條目的 timeout 一直在隨著時間變化,標誌著它們在多少秒之後會被刪除。


如果要重新為某個條目指定 timeout 參數,要使用 -exit 這一選項。


ipset -exist add obiwan 1.2.3.4 timeout 100 

這樣 1.2.3.4 這一條數據的 timeout 值就變成了 100,如果這裡設置 300,那麼它的 timeout,也就是存活時間又重新變成 300。


如果在創建集合是沒有指定 timeout,那麼之後添加條目也就不支持 timeout 參數,執行 add 會收到報錯。想要默認條目不會過期(自動刪除),又需要添加某些條目時加上 timeout 參數,可以在創建集合時指定 timeout 為 0。


ipset create luke hash:ip 
ipset add luke 5.5.5.5 timeout 100
# 得到報錯信息 kernel error received: Unknown error -1

更大!


hashsize, maxelem 這兩個參數分別指定了創建集合時初始的 hash 大小,和最大存儲的條目數量。


ipset create yoda hash:ip,port hashsize 4096 maxelem 1000000 
ipset add yoda 3.4.5.6,3306

這樣創建了名為 yoda 的集合,初始 hash 大小是 4096,如果滿了,這個 hash 會自動擴容為之前的兩倍。最大能存儲的數量是 100000 個。


如果沒有指定,hashsize 的默認值是 1024,maxelem 的默認值是 65536。


另外幾條常用命令


ipset del yoda x.x.x.x # 從 yoda 集合中刪除內容 
ipset list yoda # 查看 yoda 集合內容
ipset list # 查看所有集合的內容
ipset flush yoda # 清空 yoda 集合
ipset flush # 清空所有集合
ipset destroy yoda # 銷毀 yoda 集合
ipset destroy # 銷毀所有集合
ipset save yoda # 輸出 yoda 集合內容到標準輸出
ipset save # 輸出所有集合內容到標準輸出
ipset restore # 根據輸入內容恢復集合內容

還有……



  • 如果創建集合是指定的存儲內容包含 ip, 例如 hash:iphash:ip,port ,在添加條目時,可以填 IP 段,但是仍然是以單獨一個個 IP 的方式來存。

  • 上面所有的例子都是用 hash 的方式進行存儲,實際上 ipset 還可以以 bitmap 或者 link 方式存儲,用這兩種方式創建的集合大小,是固定的。

  • 通過 man upsetipset —help 可以查到更多的內容,包括各種選項,支持的類型等等。


轉載自https://intxt.net/block-ip-with-ipset/



lyt0112 發表在 痞客邦 留言(0) 人氣()


















Linux 信號signal處理機制



 


 
      信號機制是進程之間相互傳遞消息的一種方法,信號全稱為軟中斷信號,也有人稱作軟中斷。從它的命名可以看出,它的實質和使用很象中斷。所以,信號可以說是進程控制的一部分。

        一、信號的基本概念

            1、基本概念

        軟中斷信號(signal,又簡稱為信號)用來通知進程發生了非同步事件。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。注意,信號只是用來通知某進程發生了什麼事件,並不給該進程傳遞任何資料。

        到信號的進程對各種信號有不同的處理方法。處理方法可以分為三類:第一種是類似中斷的處理常式,對於需要處理的信號,進程可以指定處理函數,由該函數來處 理。第二種方法是,忽略某個信號,對該信號不做任何處理,就象未發生過一樣。第三種方法是,對該信號的處理保留系統的預設值,這種缺省操作,對大部分的信 號的缺省操作是使得進程終止。進程通過系統調用signal來指定進程對某個信號的處理行為。

        在進程表的表項中有一個軟中斷信號域,該域中每一位元對應一個信號,當有信號發送給進程時,對應位置位元。由此可以看出,進程對不同的信號可以同時保留,但對於同一個信號,進程並不知道在處理之前來過多少個。

        2、信號的類型

        發出信號的原因很多,這裡按發出信號的原因簡單分類,以瞭解各種信號:

        1 與進程終止相關的信號。當進程退出,或者子進程終止時,發出這類信號。
        2 與進程例外事件相關的信號。如進程越界,或企圖寫一個唯讀的記憶體區域(如程式正文區),或執行一個特權指令及其他各種硬體錯誤。
        3 與在系統調用期間遇到不可恢復條件相關的信號。如執行系統調用exec時,原有資源已經釋放,而目前系統資源又已經耗盡。
        4 與執行系統調用時遇到非預測錯誤條件相關的信號。如執行一個並不存在的系統調用。
        5 在使用者態下的進程發出的信號。如進程調用系統調用kill向其他進程發送信號。
        6 與終端交互相關的信號。如使用者關閉一個終端,或按下break鍵等情況。
        7 跟蹤進程執行的信號。

      

 












































































































說明


01


SIGHUP


掛起(hangup


02


SIGINT


中斷,當使用者從鍵盤按ctrl+c


03


SIGQUIT


退出,當使用者從鍵盤按quit鍵時


04


SIGILL


非法指令


05


SIGTRAP


跟蹤陷阱(trace trap),啟動進程,跟蹤代碼的執行


06


SIGIOT


IOT指令


07


SIGEMT


EMT指令


08


SIGFPE


浮點運算溢出


09


SIGKILL


殺死、終止進程


10


SIGBUS


匯流排錯誤


11


SIGSEGV


段違例(segmentation? violation),進程試圖去訪問其虛位址空間以外的位置


12


SIGSYS


系統調用中參數錯,如系統調用號非法


13


SIGPIPE


向某個非讀管道中寫入資料


14


SIGALRM


鬧鐘。當某進程希望在某時間後接收信號時發此信號


15


SIGTERM


軟體終止(software? termination


16


SIGUSR1


使用者自訂信號1


17


SIGUSR2


使用者自訂信號2


18


SIGCLD


某個子進程死


19


SIGPWR


電源故障



 

        注意 信號SIGKILLSIGSTOP既不能被捕捉,也不能被忽略。信號SIGIOTSIGABRT是一個信號。可以看出,同一個信號在不同的系統中值可能不一樣,所以建議最好使用為信號定義的名字,而不要直接使用信號的值。

二、有關信號的系統調用

     系統調用signal是進程用來設定某個信號的處理方法,系統調用kill是用來發送信號給指定進程的。這 兩個調用可以形成信號的基本操作。後兩個調用pausealarm是通過信號實現的進程暫停和計時器,調用alarm是通過信號通知進程計時器到時。所 以在這裡,我們還要介紹這兩個調用。

        1signal 系統調用

        系統調用signal用來設定某個信號的處理方法。該調用聲明的格式如下:
        void (*signal(int signum, void (*handler)(int)))(int);
        在使用該調用的進程中加入以下頭檔:
        #include <signal.h>

        上述聲明格式比較複雜,如果不清楚如何使用,也可以通過下面這種類型定義的格式來使用(POSIX的定義):
        typedef void (*sighandler_t)(int);
        sighandler_t signal(int signum, sighandler_t handler);
        但這種格式在不同的系統中有不同的類型定義,所以要使用這種格式,最好還是參考一下連線手冊。

        在調用中,參數signum指出要設置處理方法的信號。第二個參數handler是一個處理函數,或者是
        SIG_IGN:忽略參數signum所指的信號。
        SIG_DFL:恢復參數signum所指信號的處理方法為預設值。

        傳遞給信號處理常式的整數參數是信號值,這樣可以使得一個信號處理常式處理多個信號。系統調用signal返回值是指定信號signum前一次的處理常式或者錯誤時返回錯誤代碼SIG_ERR。下面來看一個簡單的例子:

        #include <signal.h>
        #include <unistd.h>
        #include <stdio.h>
        void sigroutine(int dunno) { /* 信號處理常式,其中dunno將會得到信號的值 */
        switch (dunno) {
        case 1:
        printf("Get a signal -- SIGHUP ");
        break;
        case 2:
        printf("Get a signal -- SIGINT ");
        break;
        case 3:
        printf("Get a signal -- SIGQUIT ");
        break;
        }
        return;
        }

        int main() {
        printf("process id is %d ",getpid());
        signal(SIGHUP, sigroutine); //* 下面設置三個信號的處理方法
        signal(SIGINT, sigroutine);
        signal(SIGQUIT, sigroutine);
        for (;;) ;
        }

        其中信號SIGINT由按下Ctrl-C發出,信號SIGQUIT由按下Ctrl-發出。該程式執行的結果如下:

        localhost:~$ ./sig_test
        process id is 463
        Get a signal -SIGINT //按下Ctrl-C得到的結果
        Get a signal -SIGQUIT //按下Ctrl-得到的結果
        //按下Ctrl-z將進程置於後臺
        [1]+ Stopped ./sig_test
        localhost:~$ bg
        [1]+ ./sig_test &
        localhost:~$ kill -HUP 463 //向進程發送SIGHUP信號
        localhost:~$ Get a signal SIGHUP
        kill -9 463 //向進程發送SIGKILL信號,終止進程
        localhost:~$

        2kill 系統調用

        系統調用kill用來向進程發送一個信號。該調用聲明的格式如下:
        int kill(pid_t pid, int sig);
        在使用該調用的進程中加入以下頭檔:
        #include <sys/types.h>
        #include <signal.h>

        系統調用可以用來向任何進程或進程組發送任何信號。
如果參數pid是正數,那麼該調用將信號sig發送到進程號為pid的進程。
如果pid等於0,那麼信 sig將發送給當前進程所屬進程組裡的所有進程。
如果參數pid等於-1,信號sig將發送給除了進程1和自身以外的所有進程。
如果參數pid小於- 1,信號sig將發送給屬於進程組-pid的所有進程。如果參數sig0,將不發送信號。該調用執行成功時,返回值為0;錯誤時,返回-1,並設置相應 的錯誤代碼errno。下面是一些可能返回的錯誤代碼:
        EINVAL:指定的信號sig無效。
        ESRCH:參數pid指定的進程或進程組不存在。注意,在進程表項中存在的進程,可能是一個還沒有被wait收回,但已經終止執行的僵死進程。
        EPERM 進程沒有權力將這個信號發送到指定接收信號的進程。因為,一個進程被允許將信號發送到進程pid時,必須擁有root權力,或者是發出調用的進程的UID EUID與指定接收的進程的UID或保存使用者IDsavedset-user-ID)相同。如果參數pid小於-1,即該信號發送給一個組,則該錯誤 表示組中有成員進程不能接收該信號。

        3pause系統調用

        系統調用pause的作用是等待一個信號。該調用的聲明格式如下:
        int pause(void);
        在使用該調用的進程中加入以下頭檔:
        #include <unistd.h>

        該調用使得發出調用的進程進入睡眠,直到接收到一個信號為止。該調用總是返回-1,並設置錯誤代碼為EINTR(接收到一個信號)。下面是一個簡單的範例:

        #include <unistd.h>
        #include <stdio.h>
        #include <signal.h>
        void sigroutine(int unused) {
        printf("Catch a signal SIGINT ");
        }

        int main() {
        signal(SIGINT, sigroutine);
        pause();
        printf("receive a signal ");
        }

        在這個例子中,程式開始執行,就象進入了閉環一樣,這是因為進程正在等待信號,當我們按下Ctrl-C時,信號被捕捉,並且使得pause退出等候狀態。

4alarm setitimer系統調用

        系統調用alarm的功能是設置一個計時器,當計時器計時到達時,將發出一個信號給進程。該調用的聲明格式如下:
        unsigned int alarm(unsigned int seconds);
        在使用該調用的進程中加入以下頭檔:
        #include <unistd.h>

        統調用alarm安排內核為調用進程在指定的seconds秒後發出一個SIGALRM的信號。如果指定的參數seconds0,則不再發送 SIGALRM信號。後一次設定將取消前一次的設定。該調用返回值為上次定時調用到發送之間剩餘的時間,或者因為沒有前一次定時調用而返回0

        注意,在使用時,alarm只設定為發送一次信號,如果要多次發送,就要多次使用alarm調用。

        對於alarm,這裡不再舉例。現在的系統中很多程式不再使用alarm調用,而是使用setitimer調用來設置計時器,用getitimer來得到計時器的狀態,這兩個調用的聲明格式如下:
        int getitimer(int which, struct itimerval *value);
        int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
        在使用這兩個調用的進程中加入以下頭檔:
        #include <sys/time.h>

        該系統調用給進程提供了三個計時器,它們各自有其獨有的計時域,當其中任何一個到達,就發送一個相應的信號給進程,並使得計時器重新開始。三個計時器由參數which指定,如下所示:
        TIMER_REAL:按實際時間計時,計時到達將給進程發送SIGALRM信號。
        ITIMER_VIRTUAL:僅當進程執行時才進行計時。計時到達將發送SIGVTALRM信號給進程。
        ITIMER_PROF:當進程執行時和系統為該進程執行動作時都計時。與ITIMER_VIR-TUAL是一對,該計時器經常用來統計進程在使用者態和內核態花費的時間。計時到達將發送SIGPROF信號給進程。

        計時器中的參數value用來指明計時器的時間,其結構如下:
        struct itimerval {
        struct timeval it_interval; /* 下一次的取值 */
        struct timeval it_value; /* 本次的設定值 */
        };

        該結構中timeval結構定義如下:
        struct timeval {
        long tv_sec; /* */
        long tv_usec; /* 微秒,1 = 1000000 微秒*/
        };

        setitimer 調用中,參數ovalue如果不為空,則其中保留的是上次調用設定的值。計時器將it_value遞減到0時,產生一個信號,並將it_value的值設 定為it_interval的值,然後重新開始計時,如此往復。當it_value設定為0時,計時器停止,或者當它計時到期,而it_interval 0時停止。調用成功時,返回0;錯誤時,返回-1,並設置相應的錯誤代碼errno
        EFAULT:參數valueovalue是無效的指針。
        EINVAL:參數which不是ITIMER_REALITIMER_VIRTITIMER_PROF中的一個。

        下面是關於setitimer調用的一個簡單示範,在該例子中,每隔一秒發出一個SIGALRM,每隔0.5秒發出一個SIGVTALRM信號:

        #include <signal.h>
        #include <unistd.h>
        #include <stdio.h>
        #include <sys/time.h>
        int sec;

        void sigroutine(int signo) {
        switch (signo) {
        case SIGALRM:
        printf("Catch a signal -- SIGALRM ");
        break;
        case SIGVTALRM:
        printf("Catch a signal -- SIGVTALRM ");
        break;
        }
        return;
        }

        int main() {
        struct itimerval value,ovalue,value2;
        sec = 5;

        printf("process id is %d ",getpid());
        signal(SIGALRM, sigroutine);
        signal(SIGVTALRM, sigroutine);

        value.it_value.tv_sec = 1;
        value.it_value.tv_usec = 0;
        value.it_interval.tv_sec = 1;
        value.it_interval.tv_usec = 0;
        setitimer(ITIMER_REAL, &value, &ovalue);

        value2.it_value.tv_sec = 0;
        value2.it_value.tv_usec = 500000;
        value2.it_interval.tv_sec = 0;
        value2.it_interval.tv_usec = 500000;
        setitimer(ITIMER_VIRTUAL, &value2, &ovalue);

        for (;;) ;
        }

        該例子的螢幕拷貝如下:

        localhost:~$ ./timer_test
        process id is 579
        Catch a signal SIGVTALRM
        Catch a signal SIGALRM
        Catch a signal SIGVTALRM
        Catch a signal SIGVTALRM
        Catch a signal SIGALRM
        Catch a signal GVTALRM

三、參考代碼

參考 1.

#include<stdio.h>

 

char buf[]={"check lock!\n"};

main()

{

        int i,p1,p2,fd;

        fd=creat("lock.dat",0644);

        write(fd,buf,20);

        while((p1=fork())==-1);

        if(p1==0)

        {

                lockf(fd,1,0);

                for (i=1;i<=3;i++)

                        printf("child1!\n");

                lockf(fd,0,0);

        }

        else{while((p2=fork())==-1);

        if (p2==0)

        {

                lockf(fd,1,0);

                for (i=1;i<=4;i++)

                        printf("child2!\n");

                lockf(fd,0,0);

        }

        else printf("parrent!\n");

        }

        close(fd);

}

 

參考 2

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

 

int waite;

 

static void start(){

   waite=0;

}

 

//自訂中斷調用函數

static void waiting(){

   while(waite==1);

}

 

main(){

   int pid1,pid2;

   while((pid1=fork())==-1);           

   if(pid1>0){

      printf("chilld process 1 is %d\n",pid1);

      while((pid2=fork())==-1);

      if(pid2>0){

         printf("child process 2 is %d\n",pid2);

         printf("please press 'delete'\n");

         waite=1;

         if(signal(SIGUSR1,start)==SIG_ERR);

         else{

            alarm(5);

            signal(SIGALRM,start);//alarm函數使用的信號

         }

         waiting();

         kill(pid1,16);//child 1 子進程發送16號中斷

         kill(pid2,17);//child 2 子進程發送17號中斷

         wait(0);//等待兩個子進程結束

         wait(0);

         printf("parent process is killed\n");

         exit(0);

      }

      else{

         waite=1;

         signal(17,start);//接受父進程發送的17號中斷,調用信號中斷函數start()

         waiting();

         printf("child 2 is killed\n");

         exit(0);

      }

   }

   else{

     waite=1;

     signal(16,start);//接受父進程發送的16號中斷,調用信號中斷函數start()

     waiting();

     printf("child 1 is killed\n");

     exit(0);

   }

}

 

參考三

#include <stdio.h>

#include <signal.h>

 

int main()

{

int i,j,stop();

signal(SIGINT,stop);

if(i=fork())

{

        if(j=fork())

        {

                //signal(SIGINT,SIG_IGN);

                sleep(10);

                kill(i,15);

                kill(j,16);

                wait(0);

                wait(0);

                printf("Parent process is killed!\n");

        }

        else {

                signal(16,SIG_IGN);

                sleep(10);

                //signal(16,stop);

                printf("Child process 3 is killed!\n");

                exit(0);

        }     

}

else {

        signal(15,SIG_IGN);

        sleep(10);

        //signal(15,stop);

        printf("Child process 1 is killed!\n");

        exit(0);

}

}

 

stop()

{

//printf("del key is got!\n");

}

 

 

參考四

#include <stdio.h>

#include <unistd.h>

#include <stdio.h>

#include <signal.h>

 

int pid1,pid2;

 

main()

{

int fd[2];

char OutPipe[100],InPipe[100];

pipe(fd);

for(;;)

{

        while((pid1=fork())==-1);

        if(pid1 == 0)

        {

                lockf(fd[1],1,0);

                sprintf(OutPipe,"Child process 1 is sending message!\n");

                write(fd[1],OutPipe,50);

                sleep(3);

                lockf(fd[1],0,0);

                exit(0);

        }

        else {

                while((pid2=fork())==-1);

                if(pid2 == 0)

                {

                        lockf(fd[1],1,0);

                        sprintf(OutPipe,"Child process 2 is sending message!\n");

                        write(fd[1],OutPipe,50);

                        sleep(3);

                        lockf(fd[1],0,0);

                }

                else {

                        wait(0);

                        read(fd[0],InPipe,50);

                        printf("%s\n",InPipe);

                }

        }

}

}

 















轉載自:http://myblog-maurice.blogspot.com/2011/12/linux-signal.html
















 

 


















lyt0112 發表在 痞客邦 留言(0) 人氣()

[root@192 ~]# cat ./test
#! /bin/bash
A="a b c d"
B="c d e f"
C=${A}"---"${B}
echo "$C"

lyt0112 發表在 痞客邦 留言(0) 人氣()

1 2
Blog Stats
⚠️

成人內容提醒

本部落格內容僅限年滿十八歲者瀏覽。
若您未滿十八歲,請立即離開。

已滿十八歲者,亦請勿將內容提供給未成年人士。