• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            colorful

            zc qq:1337220912

             

            linux 僵尸進程

            http://blog.csdn.net/zhuying_linux/article/details/7336662
            http://blog.csdn.net/fengwei321123/article/details/9301409

            如何查看并殺死僵尸進程?

            最近工作過程中,發現好幾臺服務器出現僵死進程(如圖)。

            點擊查看原圖 

              用下面的命令找出僵死進程

              ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'

              命令注解:
              -A 參數列出所有進程
              -o 自定義輸出字段 我們設定顯示字段為 stat(狀態), ppid(進程父id), pid(進程id),cmd(命令)這四個參數

              -C 用來指定所執行的命令名稱,你這里也就是讓ps僅僅顯示php命令所產生的進程的信息
                ps -C java -o lstart,pid,cmd【不過貌似打印的不全~】
                   ps -A -o lstart,pid,args |grep java【這個可以的~】 
              因為狀態為 z或者Z 的進程為僵尸進程,所以我們使用grep抓取stat狀態為zZ進程
              運行結果參考如下

            點擊查看原圖

              這里一共出現了9個僵死進程,我們需要把它們都干掉,執行下面的命令

              kill -9 8310

              這時你再執行查找僵死的進程,發現所有僵死進程都沒了.

              補充:

              最近又遇到了個問題,一臺服務器上產生了100多少僵死進程,而且每一僵死進程的父進程都不一樣,如果用上面的方法,一條一條的殺,那還不得累死我啊。
              那么就應該想一條簡單的命令,直接查找僵死進程,然后將父進程殺死~

               ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9


            ----------------------------------------------------------------------------------------------------------

            不能隨便殺父進程.
            ps -aux 先找到僵死進程ID,如5031
            lsof -p 5031看看僵死在什么地方,一般地講死鎖在某個文件或關聯在某個進程
            去除死鎖文件或殺死相關聯進程先
            -----------------------------------------------------------------------------------------------------------

             

            用ps和grep命令尋找僵尸進程
            ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'
            命令注解:
            -A 參數列出所有進程
            -o 自定義輸出字段 我們設定顯示字段為 stat(狀態), ppid(進程父id), pid(進程id),cmd(命令)這四個參數
            因為狀態為 z或者Z的進程為僵尸進程,所以我們使用grep抓取stat狀態為zZ進程
            運行結果參考如下
            Z 12334 12339 /path/cmd
            這時,我們可以使用 kill -HUP 12339來殺掉這個僵尸進程
            運行后,可以再次運行ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'來確認是否已經將僵尸進程殺死
            如果kill 子進程的無效,可以嘗試kill 其父進程來解決問題,例如上面例子父進程pid是 12334,那么我們就運行
            kill -HUP 12334
            來解決問題

             


            posted @ 2013-08-12 10:31 多彩人生 閱讀(567) | 評論 (0)編輯 收藏

            linux signal量

            轉自:http://www.dbafree.net/?p=870
            http://news.cnblogs.com/n/146220/

            我們可以使用kill -l查看所有的信號量解釋,但是沒有看到SIGNAL 0的解釋。

            [root@testdb~]# kill -l  1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL  5) SIGTRAP      6) SIGABRT      7) SIGBUS       

            8)

             SIGFPE  9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2 13) SIGPIPE     14) SIGALRM     15) SIGTERM     17) SIGCHLD 18) SIGCONT     19) SIGSTOP     20) SIGTSTP     21) SIGTTIN 22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ 26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO 30) SIGPWR      31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1 36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4  39) SIGRTMIN+5 40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8  43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6  59) SIGRTMAX-5 60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2  63) SIGRTMAX-1 64) SIGRTMAX

            網上搜了下,在這篇文檔中找到了signal 0的解釋,很不錯:

            http://www.linuxjournal.com/content/monitoring-processes-kill-0

            “signal 0″ is kind of like a moral equivalent of “ping”.

            Using “kill -0 NNN” in a shell script is a good way to tell if PID “NNN” is alive or not:

            signal 0 is just used to check process is exists or not.

            在關其它的信號量說明,原文:http://hi.baidu.com/syqust/blog/item/cd8f6c633b8a617c0d33fa35.html

            信號本質
            信號是在軟件層次上對中斷機制的一種模擬,在原理上,一個進程收到一個信號與處理器收到一個中斷請求可以說是一樣的。信號是異步的,一個進程不必通過任何操作來等待信號的到達,事實上,進程也不知道信號到底什么時候到達。

            信號是進程間通信機制中唯一的異步通信機制,可以看作是異步通知,通知接收信號的進程有哪些事情發生了。信號機制經過POSIX實時擴展后,功能更加強大,除了基本通知功能外,還可以傳遞附加信息。

            使用kill -l就會顯示出linux支持的信號列表。
            其中列表中,編號為1 ~ 31的信號為傳統UNIX支持的信號,是不可靠信號(非實時的),編號為32 ~ 63的信號是后來擴充的,稱做可靠信號(實時信號)。不可靠信號和可靠信號的區別在于前者不支持排隊,可能會造成信號丟失,而后者不會。

            下面我們對編號小于SIGRTMIN的信號進行討論(下面的編號 依次對應信號 的數值為1 – 31)。

            1) SIGHUP
            本信號在用戶終端連接(正?;蚍钦?結束時發出, 通常是在終端的控制進程結束時, 通知同一session內的各個作業, 這時它們與控制終端不再關聯。

            登錄Linux時,系統會分配給登錄用戶一個終端(Session)。在這個終端運行的所有程序,包括前臺進程組和后臺進程組,一般都屬于這個 Session。當用戶退出Linux登錄時,前臺進程組和后臺有對終端輸出的進程將會收到SIGHUP信號。這個信號的默認操作為終止進程,因此前臺進 程組和后臺有終端輸出的進程就會中止。不過可以捕獲這個信號,比如wget能捕獲SIGHUP信號,并忽略它,這樣就算退出了Linux登錄,wget也 能繼續下載。

            此外,對于與終端脫離關系的守護進程,這個信號用于通知它重新讀取配置文件。

            2) SIGINT
            程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl-C)時發出,用于通知前臺進程組終止進程。

            3) SIGQUIT
            和SIGINT類似, 但由QUIT字符(通常是Ctrl-\)來控制. 進程在因收到SIGQUIT退出時會產生core文件, 在這個意義上類似于一個程序錯誤信號。

            4) SIGILL
            執行了非法指令. 通常是因為可執行文件本身出現錯誤, 或者試圖執行數據段. 堆棧溢出時也有可能產生這個信號。

            5) SIGTRAP
            由斷點指令或其它trap指令產生. 由debugger使用。

            6) SIGABRT
            調用abort函數生成的信號。

            7) SIGBUS
            非法地址, 包括內存地址對齊(alignment)出錯。比如訪問一個四個字長的整數, 但其地址不是4的倍數。它與SIGSEGV的區別在于后者是由于對合法存儲地址的非法訪問觸發的(如訪問不屬于自己存儲空間或只讀存儲空間)。

            8) SIGFPE
            在發生致命的算術運算錯誤時發出. 不僅包括浮點運算錯誤, 還包括溢出及除數為0等其它所有的算術的錯誤。

            9) SIGKILL
            用來立即結束程序的運行. 本信號不能被阻塞、處理和忽略。如果管理員發現某個進程終止不了,可嘗試發送這個信號。

            10) SIGUSR1
            留給用戶使用

            11) SIGSEGV
            試圖訪問未分配給自己的內存, 或試圖往沒有寫權限的內存地址寫數據.

             信號 11,即表示程序中可能存在特定條件下的非法內存訪問。

            12) SIGUSR2
            留給用戶使用

            13) SIGPIPE
            管道破裂。這個信號通常在進程間通信產生,比如采用FIFO(管道)通信的兩個進程,讀管道沒打開或者意外終止就往管道寫,寫進程會收到SIGPIPE信號。此外用Socket通信的兩個進程,寫進程在寫Socket的時候,讀進程已經終止。

            14) SIGALRM
            時鐘定時信號, 計算的是實際的時間或時鐘時間. alarm函數使用該信號.

            15) SIGTERM
            程序結束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理。通常用來要求程序自己正常退出,shell命令kill缺省產生這個信號。如果進程終止不了,我們才會嘗試SIGKILL。

            17) SIGCHLD
            子進程結束時, 父進程會收到這個信號。

            如果父進程沒有處理這個信號,也沒有等待(wait)子進程,子進程雖然終止,但是還會在內核進程表中占有表項,這時的子進程稱為僵尸進程。這種情 況我們應該避免(父進程或者忽略SIGCHILD信號,或者捕捉它,或者wait它派生的子進程,或者父進程先終止,這時子進程的終止自動由init進程 來接管)。

            18) SIGCONT
            讓一個停止(stopped)的進程繼續執行. 本信號不能被阻塞. 可以用一個handler來讓程序在由stopped狀態變為繼續執行時完成特定的工作. 例如, 重新顯示提示符

            19) SIGSTOP
            停止(stopped)進程的執行. 注意它和terminate以及interrupt的區別:該進程還未結束, 只是暫停執行. 本信號不能被阻塞, 處理或忽略.

            20) SIGTSTP
            停止進程的運行, 但該信號可以被處理和忽略. 用戶鍵入SUSP字符時(通常是Ctrl-Z)發出這個信號

            21) SIGTTIN
            當后臺作業要從用戶終端讀數據時, 該作業中的所有進程會收到SIGTTIN信號. 缺省時這些進程會停止執行.

            22) SIGTTOU
            類似于SIGTTIN, 但在寫終端(或修改終端模式)時收到.

            23) SIGURG
            有”緊急”數據或out-of-band數據到達socket時產生.

            24) SIGXCPU
            超過CPU時間資源限制. 這個限制可以由getrlimit/setrlimit來讀取/改變。

            25) SIGXFSZ
            當進程企圖擴大文件以至于超過文件大小資源限制。

            26) SIGVTALRM
            虛擬時鐘信號. 類似于SIGALRM, 但是計算的是該進程占用的CPU時間.

            27) SIGPROF
            類似于SIGALRM/SIGVTALRM, 但包括該進程用的CPU時間以及系統調用的時間.

            28) SIGWINCH
            窗口大小改變時發出.

            29) SIGIO
            文件描述符準備就緒, 可以開始進行輸入/輸出操作.

            30) SIGPWR
            Power failure

            31) SIGSYS
            非法的系統調用。

            在以上列出的信號中,程序不可捕獲、阻塞或忽略的信號有:SIGKILL,SIGSTOP
            不能恢復至默認動作的信號有:SIGILL,SIGTRAP
            默認會導致進程流產的信號有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ
            默認會導致進程退出的信號有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM
            默認會導致進程停止的信號有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU
            默認進程忽略的信號有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH

            此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在進程掛起時是繼續,否則是忽略,不能被阻塞

            終止程序的時候在不得已的情況下不能用SIGKILL,因為SIGKILL不會對子進程進行處理,只是把對自己進行處理

             

             

            Linux支持POSIX標準信號和實時信號。下面給出Linux Signal的簡表,詳細細節可以查看man 7 signal。

             

            默認動作的含義如下:

            Term    終止進程

             

            信號 取值 默認動作 含義(發出信號的原因)
            SIGHUP 1 Term 終端的掛斷或進程死亡
            SIGINT 2 Term 來自鍵盤的中斷信號
            SIGQUIT 3 Core 來自鍵盤的離開信號
            SIGILL 4 Core 非法指令
            SIGABRT 6 Core 來自abort的異常信號
            SIGFPE 8 Core 浮點例外
            SIGKILL 9 Term 殺死
            SIGSEGV 11 Core 段非法錯誤(內存引用無效)
            SIGPIPE 13 Term 管道損壞:向一個沒有讀進程的管道寫數據
            SIGALRM 14 Term 來自alarm的計時器到時信號
            SIGTERM 15 Term 終止
            SIGUSR1 30,10,16 Term 用戶自定義信號1
            SIGUSR2 31,12,17 Term 用戶自定義信號2
            SIGCHLD 20,17,18 Ign 子進程停止或終止
            SIGCONT 19,18,25 Cont 如果停止,繼續執行
            SIGSTOP 17,19,23 Stop 非來自終端的停止信號
            SIGTSTP 18,20,24 Stop 來自終端的停止信號
            SIGTTIN 21,21,26 Stop 后臺進程讀終端
            SIGTTOU 22,22,27 Stop 后臺進程寫終端
            SIGBUS 10,7,10 Core 總線錯誤(內存訪問錯誤)
            SIGPOLL Term Pollable事件發生(Sys V),與SIGIO同義
            SIGPROF 27,27,29 Term 統計分布圖用計時器到時
            SIGSYS 12,-,12 Core 非法系統調用(SVr4)
            SIGTRAP 5 Core 跟蹤/斷點自陷
            SIGURG 16,23,21 Ign socket緊急信號(4.2BSD)
            SIGVTALRM 26,26,28 Term 虛擬計時器到時(4.2BSD)
            SIGXCPU 24,24,30 Core 超過CPU時限(4.2BSD)
            SIGXFSZ 25,25,31 Core 超過文件長度限制(4.2BSD)
            SIGIOT 6 Core IOT自陷,與SIGABRT同義
            SIGEMT 7,-,7 Term
            SIGSTKFLT -,16,- Term 協處理器堆棧錯誤(不使用)
            SIGIO 23,29,22 Term 描述符上可以進行I/O操作
            SIGCLD -,-,18 Ign 與SIGCHLD同義
            SIGPWR 29,30,19 Term 電力故障(System V)
            SIGINFO 29,-,- 與SIGPWR同義
            SIGLOST -,-,- Term 文件鎖丟失
            SIGWINCH 28,28,20 Ign 窗口大小改變(4.3BSD, Sun)
            SIGUNUSED -,31,- Term 未使用信號(will be SIGSYS)

             

            說明:

            一些信號的取值是硬件結構相關的(一般alpha和sparc架構用第一個值,i386、ppc和sh架構用中間值,mips架構用第三個值, - 表示相應架構的取值未知)。

             

            藍色的是POSIX.1-1990標準信號。

            SIGKILL和SIGSTOP信號不能被掛鉤、阻塞或忽略。

             

            青色的是SUSv2和POSIX.1-2001定義的信號。

            在Linux 2.2(包括)內核之前,SIGSYS、SIGXCPU、SIGXFSZ和SIGBUS (SPARC和MIPS架構除外)的默認動作是終止進程,但沒有 core dump。Linux 2.4遵循POSIX.1-2001要求,這些信號的默認動作改為:終止進程同時做core dump。

             

            橙色的是其他常見的信號。

            信號29在Alpha上為SIGINFO / SIGPWR ,在Sparc上為SIGLOST。

            SIGEMT沒有在POSIX.1-2001中說明,但是在大多數的Unices中仍然能見到,典型的默認動作是終止進程并做core dump。

            SIGPWR沒有在POSIX.1-2001中說明,在使用它的一些Unices中典型的默認動作是忽略。

            SIGIO沒有在POSIX.1-2001中說明,在使用它的一些Unices中典型的默認動作是忽略。

             

            進程可以通過使用sigaction和signal系統調用來改變信號的默認處理方式(使用signal的可移植性差)。進程可以選擇下列3種信號處理方式中的一種:

            1、執行默認操作;

            2、忽略該信號;

            3、捕獲該信號,但是通過信號句柄來調用自定義的處理函數。

             

            信號可能被阻塞。進程中的每個線程擁有獨立的信號掩碼,用來表示本線程的信號被阻塞。線程通過pthread_sigmask來設置它的信號掩碼。單線程程序可以用sigprocmask來操作信號掩碼。在多線程程序中,所有線程處理一個指定信號的默認行為都是一樣的。

             

             

            補充:

            SIG_DFL,SIG_IGN 分別表示無返回值的函數指針,指針值分別是0和1,這兩個指針值邏輯上講是實際程序中不可能出現的函數地址值。

            SIG_DFL:默認信號處理程序
            SIG_IGN:忽略信號的處理程序

            posted @ 2013-08-12 09:09 多彩人生 閱讀(455) | 評論 (0)編輯 收藏

            wxWidgets中wxString各類型轉換

            http://www.cnzui.com/archives/290#std::string_to_wxString

            目錄

               附加(數據庫ADO類型):

            文本

            A literal is a string written in code with "quotes around it". A literal is not a wxString, and (in wxWidgets 2.8) will not be implicitly converted to one. This means that you can never pass in a raw literal into a wxWidget function or method (unless you don't care about your app not building with Unicode-enabled wxWidgets builds)
            文本是一個在代碼中被引號包圍的串,文本它不是一個單純的wxString類型,并且(在wxWidgets 2.8中)不能被隱含的轉換為一個wxString類型。這意味著你不能試圖將光禿禿的將一段文本放到wxWidget函數或方法中通過編譯(除非你不在 意你的應用程序是需要在Unicode編碼環境中通過編譯的)。

            MessageBox("I'm a mistake!")  // WRONG in WxWidgets 2.8 (OK in 2.9) 

            Instead, wxWidgets (prior to wxWidgets 2.9) requires you to use one of these macros to turn literals into wxString-compatible characters:

            _("text that can be translated") wxT("text that won't be translated") _T("same as wxT")   char* c = "sometext"; wxT(c) // WRONG, not a literal 

            Rather than being a nuisance, the _(), wxT(), and _T() macros take care of some unicode issues and help with internationalization.

            char* to wxString

            const char* chars = "Hello world"; // assuming your string is encoded as UTF-8, change the wxConv* parameter as needed wxString mystring(chars, wxConvUTF8);

            wxString to char*

            void my_function(const char* foo) { } ... wxString mystring(wxT("HelloWorld")); // you could give the encoding you want as a parameter to mb_str(), e.g. mb_str(wxConvUTF8) my_function( mystring.mb_str() );

            mb_str() 返回一個臨時的指針,如果你需要通過函數得到更多的返回結果(就和上面的情況一樣),你可以臨時保存一下這個字符數據流:

            wxString s( wxT("some string") ); wxCharBuffer buffer=s.ToUTF8(); foo( buffer.data() );  // data() returns const char * bar( buffer.data(), strlen(buffer.data()) );  // in case you need the length of the data 

            當你真的需要將它復制為char*類型時:

            wxString mystring(wxT("HelloWorld")); char cstring[1024]; // assuming you want UTF-8, change the wxConv* parameter as needed strncpy(cstring, (const char*)mystring.mb_str(wxConvUTF8), 1023);

            你也可以用ToUTF8(), 因為你得到的編碼比用mb_str()函數從const char*轉換成char*更加清楚。

            wxString mystring(wxT("HelloWorld")); (const_cast<char*>((const char*)mystring.mb_str()))

            在可變參數的函數 (如printf)中用mb_str()函數將無效,但按以下的方法是有效的:

            wxString mystring(wxT("HelloWorld")); printf("%s",mystring.mb_str().data());

            做為選擇,使用Potential Unicode Pitfalls中推薦的方法:

            printf("%s", (const char*)mystring.mb_str())

            wchar_t* to wxString

            const wchar_t* chars = L"Hello world"; wxString mystring(chars);

            wxString to wchar_t*

            請翻閱官方文檔的以下方法:

            wxString::wc_str() wxString::wchar_str()

             

            wxString to TCHAR

            TCHAR tCharString[255]; wxString myString(_T("Hello World")); const wxChar* myStringChars = myString.c_str(); for (int i = 0; i < myString.Len(); i++) {    tCharString[i] = myStringChars [i]; } tCharString[myString.Len()] = _T('\0');

            int to wxString

            wxString mystring = wxString::Format(wxT("%i"),myint);

            或者

            wxString mystring; mystring << myint;

            float to wxString

            wxString mystring = wxString::Format(wxT("%f"), myfloat);

            或者

            wxString mystring; mystring << myfloat;

            wxString to integer number

            wxString number(wxT("145")); long value; if(!number.ToLong(&value)) { /* error! */ }

            或者

            wxString str = _T("123"); int num;   num = wxAtoi(str);

            wxString to floating-point number

            wxString number(wxT("3.14159")); double value; if(!number.ToDouble(&value)){ /* error! */ }

            std::string to wxString

            std::string stlstring = "Hello world"; // assuming your string is encoded as UTF-8, change the wxConv* parameter as needed wxString mystring(stlstring.c_str(), wxConvUTF8);

            從wxWidgets 2.9開始, 你可以用適當的構造函數:

            std::string stlstring = "Hello world"; // assuming your string is encoded as the current locale encoding (wxConvLibc) wxString mystring(stlstring);

            wxString to std::string

            在wxWidgets 2.8 :

            wxString mystring(wxT("HelloWorld")); std::string stlstring = std::string(mystring.mb_str());

            在wxWidgets 2.9, 你可以用這個方法

            wxString::ToStdString()

            std::wstring to wxString

            從wxWidgets 2.9開始, 你可以用適當的構造函數:

            std::sstring stlstring = L"Hello world"; // assuming your string is encoded as the current locale encoding (wxConvLibc) wxString mystring(stlstring);

            wxString to std::wstring

            在wxWidgets 2.9, 你可以用這個方法

            wxString::ToStdWstring()


            附:(數據庫類型)

            " src="/CuteSoft_Client/CuteEditor/Images/anchor.gif">wxString 轉 _bstr_t
             

            wxString str(wxT("Hello")); _bstr_t mystring=_bstr_t(str.wc_str()); 

            " src="/CuteSoft_Client/CuteEditor/Images/anchor.gif">_bstr_ 轉 wxString
            _bstr_t bstr="hello"; wxString mystring = wxString(static_cast<const wchar_t *>(bstr)); 

            " src="/CuteSoft_Client/CuteEditor/Images/anchor.gif">_variant_t 轉 wxString

            _variant_t  varstr=_variant_t("Hello"); wxString mystring=wxString(static_cast<const wchar_t *>(_bstr_t(varstr))); 

            " src="/CuteSoft_Client/CuteEditor/Images/anchor.gif">wxString 轉 _variant_t

            wxString str(wxT("Hello")); _variant_t myvar=_variant_t(str.wc_str()); 

             

            本文翻譯自wxWidgets官方:http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString

            posted @ 2013-08-10 09:29 多彩人生 閱讀(4416) | 評論 (1)編輯 收藏

            make makefile 學習

            http://www.cnblogs.com/napoleon_liu/archive/2011/05/06/2039316.html
            http://www.iteye.com/topic/774919
            http://blog.csdn.net/liangkaiming/article/details/6267357
            http://blog.jobbole.com/44891/


            gcc是C編譯器;g++是C++編譯器;linux下cc一般是一個符號連接,指向gcc;gcc和g++都是GUN(組織)的編譯器。而CC則一般是makefile里面的一個名字,即宏定義,嘿,因為Linux/Unix都是大小寫敏感的系統,這點一定要注意。

            cc是Unix系統的C Compiler,而gcc則是GNU Compiler Collection,GNU編譯器套裝。gcc原名為Gun C語言編譯器,因為它原本只能處理C語言,但gcc很快地擴展,包含很多編譯器(C、C++、Objective-C、Ada、Fortran、 Java)。因此,它們是不一樣的,一個是古老的C編譯器,一個是GNU編譯器集合,gcc里面的C編譯器比cc強大多了,因此沒必要用cc。

            下載不到cc的原因在于:cc來自于昂貴的Unix系統,cc是商業軟件。

            Linux下的cc是gcc符號連接,可以通過$ls –l /usr/bin/cc來簡單察看,該變量是make程序的內建變量,默認指向gcc。cc符號鏈接和變量存在的意義在于源碼的移植性,可以方便的用 gcc來編譯老的用cc編譯的Unix軟件,甚至連makefile都不用改在,而且也便于Linux程序在Unix下編譯。

             

            誤區一:gcc只能編譯C代碼,g++只能編譯C++代碼。

            兩者都可以,但請注意:

            (1)后綴為.c的,gcc把它當作是C程序,而g++當作是c++程序;后綴為.cpp的,兩者都會認為是C++程序,注意,雖然C++是C的超集,但是兩者對語法的要求是有區別的。C++的語法規則更加嚴謹一些。

            (2)編譯階段,g++會調用gcc,對于C++代碼,兩者是等價的,但是因為gcc命令不能自動和C++程序使用的庫聯接,所以通常用g++來完成鏈接,為了統一起見,干脆編譯/鏈接統統用g++了(編譯階段g++會反過來再調用gcc),這就給人一種錯覺,好像cpp程序只能用g++似的。

             

            誤區二:gcc不會定義__cplusplus宏,而g++會

            實際上,這個宏只是標志著編譯器將會把代碼按C還是C++語法來解釋,如上所述,如果后綴為.c,并且采用gcc編譯器,則該宏就是未定義的,否則,就是已定義。

             

            誤區三:編譯只能用gcc,鏈接只能用g++

            嚴格來說,這句話不算錯誤,但是它混淆了概念,應該這樣說:編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++。因為gcc命令不能自動和C++程序使用的庫聯接,所以通常使用g++來完成聯接。但在編譯階段,g++會自動調用gcc,二者等價。

             

            C++的編譯器肯定可以編譯C的代碼,注意除了C++對C的語法擴充之外,編譯和鏈接C和C++的標準庫通常也不一樣呢,用gcc而非g++也編譯了C++的程序就證明了這一點。

             

            注:符號鏈接是一種特殊類型的文件,它的內容只是一個字符串。它可能指向一個存在的文件也可能什么都不指向。當您在命令行或程序里提到符號鏈接的時候,您實際上進入了它指向的文件,前提是這個文件是存在的。

            posted @ 2013-08-07 20:04 多彩人生 閱讀(348) | 評論 (0)編輯 收藏

            jsoncpp簡單示例

            http://www.cnblogs.com/logicbaby/archive/2011/07/03/2096794.html

            1、 編譯jsoncpp
              從(http://jsoncpp.sourceforge.net/)下載源碼包“jsoncpp-src-0.5.0.tar.gz”,解壓后在其解壓后目錄中運行
            $ scons platform=linux-gcc
               編譯出來的庫文件在其libs/ linux-gcc-4.4.2目錄下,有libjson_linux-gcc-4.4.2_libmt.so和libjson_linux-gcc- 4.4.2_libmt.a。頭文件在解壓目錄下的include中。我的jsoncpp安裝在$HOME/usr/jsoncpp下。

            $ mkdir ~/usr/jsoncpp

            $ cp -r include ~/usr/jsoncpp

            $ cp -r libs ~/usr/jsoncpp

            2、 Jsoncpp簡單實例

            1) 反序列化Json對象
              比如一個Json對象的字符串序列如下,其中”array”:[...]表示Json對象中的數組:

            {“key1”:”value1”,”array”:[{“key2”:”value2”},{“key2”:”value3”},{“key2”:”value4”}]}

              那怎么分別取到key1和key2的值呢,代碼如下所示:

            #include <iostream>
            #include <string>
            #include "json/json.h"
             
            int main(void)
            {
                 std::string strValue = "{\"key1\":\"value1\",\"array\":[{\"key2\":\"value2\"},{\"key2\":\"value3\"},{\"key2\":\"value4\"}]}";
             
                 Json::Reader reader;
                 Json::Value value;
             
                 if (reader.parse(strValue, value))
                 {
                  std::string out = value["key1"].asString();
                  std::cout << out << std::endl;
                  const Json::Value arrayObj = value["array"];
                  for (int i=0; i<arrayObj.size(); i++)
                  {
                       out = arrayObj[i]["key2"].asString();
                       std::cout << out;
                       if (i != arrayObj.size() - 1)
                        std::cout << std::endl;
                  }
                 }
                 return 0;
            }
            編譯連接
            $ g++ jscpp1.cpp -I$HOME/usr/jsoncpp/include/ ~/usr/jsoncpp/libs/linux-gcc-4.5.2/libjson_linux-gcc-4.5.2_libmt.a
            $ ./a.out
            value1
            value2
            value3
            value4

            2)序列化Json對象
              先構建一個Json對象,此Json對象中含有數組,然后把Json對象序列化成字符串,代碼如下:
            #include <iostream>
            #include <string>
            #include "json/json.h"
             
            int main(void)
            {
                 Json::Value root;
                 Json::Value arrayObj;
                 Json::Value item;
             
                 for (int i = 0; i < 10; i ++)
                 {
                  item["key"] = i;
                  arrayObj.append(item);
                 }
             
                 root["key1"] = "value1";
                 root["key2"] = "value2";
                 root["array"] = arrayObj;
                 //root.toStyledString();
                 std::string out = root.toStyledString();
                 std::cout << out << std::endl;
                 return 0;
            }

            編譯連接
            $ g++ jscpp2.cpp -I$HOME/usr/jsoncpp/include/ ~/usr/jsoncpp/libs/linux-gcc-4.5.2/libjson_linux-gcc-4.5.2_libmt.a
            $ ./a.out
            {
               "array" : [
                  {
                     "key" : 0
                  },
                  {
                     "key" : 1
                  },
                  {
                     "key" : 2
                  },
                  {
                     "key" : 3
                  },
                  {
                     "key" : 4
                  },
                  {
                     "key" : 5
                  },
                  {
                     "key" : 6
                  },
                  {
                     "key" : 7
                  },
                  {
                     "key" : 8
                  },
                  {
                     "key" : 9
                  }
               ],
               "key1" : "value1",
               "key2" : "value2"
            }


              注:以上兩個代碼來自網上,這兩個實例很好,故在此借用。

            posted @ 2013-08-05 16:07 多彩人生 閱讀(1748) | 評論 (0)編輯 收藏

            curl 多線程

            http://fool.is-programmer.com/2011/3/26/libcurl-signal-bug.25603.html
            http://blog.csdn.net/balderfan/article/details/7599554
            http://blog.chinaunix.net/uid-20692625-id-3203258.html

            posted @ 2013-08-04 19:15 多彩人生 閱讀(500) | 評論 (0)編輯 收藏

            讓CentOS默認生成core dump

            CentOS中默認設置了ulimit -c 0也就是默認程序不生成core dump,這樣很麻煩,每次啟動程序前都要讓用戶先執行一次ulimit -c ulimited,有時候用戶忘記則不生成core,很不利于錯誤分析,所以研究了下如何讓系統默認就生成core.

            在網上找了部分資料,看到了

            CentOS 5中ulimit值調整并永久生效的方法

            http://www.sunchis.com/html/os/linux/2011/0609/338.html

            這篇文章,其中說通過編輯/etc/security/limits.conf文件可以實現ulimit的值設定,測試了nofile后的確可行,但是寫入了

            * soft core unlimited
            * hard core unlimited


            重新登陸卻沒有效果  // ps by zc, 我到這里就有效果了

            [root@localhost ~]# ulimit -a
            core file size          (blocks, -c) 0

            通過研究,發現/etc/profile文件中有一句

            # No core files by default
            ulimit -S -c 0 > /dev/null 2>&1

            二話不說,把第二行用#注釋掉后,即

            # No core files by default
            #ulimit -S -c 0 > /dev/null 2>&1

            保存重新登陸用戶,再次查看,一切正常!

            [root@localhost ~]# ulimit -a
            core file size          (blocks, -c) ulimited


            -----------------------------------------------------------------

            1:設置系統允許生產core文件
            在 ~/.bash_profile 中增加
            ulimit -c unlimited
            使用ulimit -a可以查看系統core文件的大小限制;
            使用ulimit -c [kbytes]可以設置系統允許生成的core文件大小;
            ulimit -c 0 不產生core文件
            ulimit -c 100 設置core文件最大為100k
            ulimit -c unlimited 不限制core文件大小

            posted @ 2013-07-31 10:34 多彩人生 閱讀(7628) | 評論 (0)編輯 收藏

            apache 開啟多站點


            http://zhangyong333revice.blog.163.com/blog/static/1131518832011101811237149/
            http://hi.baidu.com/dspace/item/68b67705a9c53bd21ff046a1
            http://zhb1208.iteye.com/blog/1432957
            http://zhidao.baidu.com/question/285759208.html
            http://michaelkang.blog.51cto.com/1553154/1065251
            http://blog.sina.com.cn/s/blog_7e56997901016bw7.html
            http://wenku.baidu.com/view/95b2361ca8114431b90dd8c0.html
            http://www.cnblogs.com/see7di/archive/2011/06/15/2239756.html
            http://zhidao.baidu.com/question/472396507.html
            http://blog.csdn.net/yongshiok/article/details/6936960
            http://www.xker.com/page/e2010/0925/98279.html
            http://www.codesky.net/article/201101/149128.html

            如何更改linux下的Apache端口號

            一、修改/etc/httpd/conf/httpd.conf文件中的監聽端口號

            Listen 80

            把80修改成需要的號,如8000,即

            Listen 8000
            二、查看SELinux下http相關端口

            # semanage port -l|grep http
            http_cache_port_t              tcp      3128, 8080, 8118, 10001-10010
            http_cache_port_t              udp      3130
            http_port_t                    tcp      80, 443, 488, 8008, 8009, 8443
            pegasus_http_port_t            tcp      5988
            pegasus_https_port_t           tcp      5989

            發現8000不在其范圍之內,所以需要另外添加,方法如下:

            # semanage port -a -t http_port_t -p tcp 8000

            再次查看,

            # semanage port -l|grep http
            http_cache_port_t              tcp      3128, 8080, 8118, 10001-10010
            http_cache_port_t              udp      3130
            http_port_t                    tcp      8000, 80, 443, 488, 8008, 8009, 8443
            pegasus_http_port_t            tcp      5988
            pegasus_https_port_t           tcp      5989

            三、在防火墻中開放新添加的端口

            修改/etc/sysconfig/iptables文件,在文件中添加如一行:

            -A INPUT -m state --state NEW -m tcp -p tcp --dport 8008 -j ACCEPT

            四、重啟防火墻和Apache

            # service iptables restart

            # service httpd restart

            五、正常情況下,應該可以通過新端口訪問WEB服務了。

            注:

            1、第二、三、四步驟是在系統已經開啟SELinux和防火墻的情況下設置的,如果已經關閉此兩個服務,修改端口后直接重啟Apache即可;

            2、修改的端口號可以是執行#semanage port -l|grep http后,默認已經有的端口,如8443,這樣可以省略額外添加SELinux端口操作;

            3、第三步操作可以圖形界面下完成。

            參考資料

            1、Permission denied: make_sock: could not bind to address

             http://emmune.blogspot.com/2009/07/permission-denied-makesock-could-not.html

            不熟悉python、plone、zope,想用apache。80端口已經不在,就征用81端口湊合吧。修改httpd.conf后apachectl start,結果:
            (13)Permission denied: make_sock: could not bind to address [::]:81
            (13)Permission denied: make_sock: could not bind to address 0.0.0.0:81

            查一下SELinux下http相關端口 semanage port -l|grep http,結果:
            http_cache_port_t tcp 3128, 8080, 8118, 10001-10010
            http_cache_port_t udp 3130
            http_port_t tcp 80, 443, 488, 8008, 8009, 8443
            pegasus_http_port_t tcp 5988
            pegasus_https_port_t tcp 5989

            直接用man semanage最后例子中的一句
            # Allow Apache to listen on port 81
            semanage port -a -t http_port_t -p tcp 81
            然后再apachectl start,OK。使用域名:81能夠訪問啦。

            注:semanage
            semanage is used to configure certain elements of SELinux policy without requiring modification to or recompilation from policy sources. This includes the mapping from Linux usernames to SELinux user identities (which controls the initial security context assigned to Linux users when they login and bounds their authorized role set) as well as security context mappings for various kinds of objects, such as network ports, interfaces, and nodes(hosts) as well as the file context mapping. See the EXAMPLES section below for some examples of common usage. Note that the semanage login command deals with the mapping from Linux usernames (logins) to SELinux user identities, while the semanage user command deals with the mapping from SELinux user identities to authorized role sets. In most cases, only the former mapping needs to be adjusted by the administrator; the latter is principally defined by the base policy and usually does not require modification.

            2、linux 下apche無法監聽端口解決辦法

            http://www.zzxj.net/blog/fxs_2008/archive/2010/07/05/187.html

            想建立一個測試用的虛擬主機,遇到了這個問題:
            [root@localhost html]# service httpd start
            Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.termwikidev for ServerName
            (13)Permission denied: make_sock: could not bind to address [::]:81
            (13)Permission denied: make_sock: could not bind to address 0.0.0.0:81
            no listening sockets available, shutting down
            Unable to open logs

            解決辦法:

            semanage port -l|grep http
            semanage port -a -t http_port_t -p tcp 81

            這個兩個命令一是查看,一個是添加,添加完再查看一遍,如果有81,則成功。另可能要以root用戶運行。

            此外,如果要外網訪問,還要打開linux的防火墻:

            [root@localhost html]# vim /etc/sysconfig/iptables
            [root@localhost html]# service iptables restart

            重啟apache.

            相關資料:

            starting httpd 13 permission denied make_sock could not bind to address2010年01月19日 星期二 11:33In Fedora Core 5/6 and RHEL 5. We have made it easier to customize certain common parts of SELinux. In previous releases of SELinux if you wanted to change simple things like which port a daemon could listen to, you would need to write policy. Now we have the semanage utility.

            SELinux assigns types to all network ports on a system. By default all ports are less then 1024 are labeled reserved_port_t and all ports > 1024 are labeled port_t. If a port is assigned to a particular type
            say the http port 80, it has an assigned type of http_port_t. If you want to look at all the assigned ports in SELinux, you can use the semanage tool, semanage port -l.

            So if you executed

            semanage port -l | grep http
            http_cache_port_t tcp 3128, 8080, 8118
            http_cache_port_t udp 3130
            http_port_t tcp 80, 443, 488, 8008, 8009, 8443
            pegasus_http_port_t tcp 5988
            pegasus_https_port_t tcp 5989

            Here we see http_port_t is assigned to ports 80, 443, 488, 8008, 8009, 8443

            The policy is written to allow httpd_t http_port_t:tcp_socket name_bind;

            This means the apache command can "bind" to an port that is labeled http_port_t.

            So lets say you want to run httpd on port 81.

            So you edit /etc/httpd/http.conf

            and change this line
            Listen 80
            to
            Listen 81


            Now restart the daemon.
            service httpd restart
            Stopping httpd: [ OK ]
            Starting httpd: (13)Permission denied: make_sock: could not bind to address [::]:81
            (13)Permission denied: make_sock: could not bind to address 0.0.0.0:81
            no listening sockets available, shutting down
            Unable to open logs
            [FAILED]

            Now the daemon fails to start because it can not bind to port 81.

            This generates an AVC that looks like

            ----
            time->Tue Dec 12 17:37:49 2006
            type=SYSCALL msg=audit(1165963069.248:852): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58b68 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=user_u:system_r:httpd_t:s0 key=(null)
            type=AVC msg=audit(1165963069.248:852): avc: denied { name_bind } for pid=21134 comm="httpd" src=81 scontext=user_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket

            To fix this you can use semanage to add the port

            semanage port -a -t http_port_t -p tcp 81

            service httpd start
            Starting httpd: [ OK ]

            posted @ 2013-07-30 18:41 多彩人生 閱讀(2173) | 評論 (0)編輯 收藏

            php socket connect Permission denied :13

            Hi there!

            For the TCP connections: socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
            In case you're having problems in socket_connect() with socket_strerror() = "Permission denied", you may be having a SELinux config issue.

            Check if SELinux is enabled:
            # /usr/sbin/sestatus -v
            In case it is, you can just type the command:
            # setsebool httpd_can_network_connect=1

            That's it... I read you had to reboot, but I didn't and it worked fine anyway. More info, you may check:
            http://arkiv.netbsd.se/?ml=squirrelmail-users&a=2005-11&t=1523021

            posted @ 2013-07-29 17:27 多彩人生 閱讀(1937) | 評論 (0)編輯 收藏

            PHP的ntohl網絡字節序函數及相關知識

            http://n3yang.com/archives/2011/12/16/php-function-ntohl/
            http://www.w3school.com.cn/php/func_misc_unpack.asp    // php unpack 函數


            最近項目中使用到了PHP與C服務器的socket通信,在做數據轉換的時候,PHP沒有提供對應將網絡字節序和機器字節序相互轉換的程序,但是根據函數的意義,我們可以做相應的轉換來實現這一函數:

            1
            2
            3
            4
            function ntohl($str){
                $arr = unpack('I', pack('N', $str));
                return $arr[1];
            }

            函數的意義
            程序的作用是將網絡字節序和機器字節序進行相互轉換。在C/C++、Python、Delphi中都提供了相應的函數“ntohl”和“htonl”,如果是short類型就是“ntohs”和“htons”。下面是這些函數的意義:

            ntohl()--"Network to Host Long" htonl()--"Host to Network Long" htons()--"Host to Network Short" ntohs()--"Network to Host Short"

            什么是主機字節序
            不同的機器字節序不相同,這與使用的CPU有關。不同的CPU在處理高位字節時所存儲的順序是不同的。
            例如Intel x86結構下, short型數0×1234表示為34 12, int型數0×12345678表示為78 56 34 12
            如IBM power PC結構下, short型數0×1234表示為12 34, int型數0×12345678表示為12 34 56 78

            網絡字節序
            正是由于每個主機的處理順序有可能不同,所以在網絡協議中規定數據從高到低順序存儲,目的是在不同架構的主機中可以正常通信,避免兼容性問題。

            posted @ 2013-07-29 14:49 多彩人生 閱讀(703) | 評論 (0)編輯 收藏

            僅列出標題
            共25頁: First 2 3 4 5 6 7 8 9 10 Last 

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            jizzjizz国产精品久久| 国产精品热久久毛片| 99久久精品费精品国产| 狠狠88综合久久久久综合网 | 久久福利资源国产精品999| 亚洲国产二区三区久久| 久久综合丁香激情久久| 久久国产精品99精品国产987| 欧美熟妇另类久久久久久不卡 | 久久综合久久伊人| 久久久黄片| 久久精品国产亚洲AV香蕉| 久久亚洲AV无码精品色午夜麻豆| 亚洲人成电影网站久久| 久久精品aⅴ无码中文字字幕不卡| 熟妇人妻久久中文字幕| 久久精品国产99久久无毒不卡| 国产精品一区二区久久不卡| 嫩草影院久久99| 中文字幕久久精品 | 狠狠色综合网站久久久久久久高清 | 国产欧美久久久精品影院| 2020国产成人久久精品| 久久丫精品国产亚洲av不卡 | 中文字幕成人精品久久不卡| 日韩亚洲国产综合久久久| 国产色综合久久无码有码| 狠狠色丁香婷婷久久综合不卡| 久久精品国产亚洲av瑜伽| 成人久久免费网站| 国产精品久久波多野结衣| 手机看片久久高清国产日韩| 色偷偷88888欧美精品久久久| 亚洲国产成人久久综合碰碰动漫3d| 超级碰碰碰碰97久久久久| 国内精品久久久久伊人av| 色婷婷综合久久久久中文字幕| 丰满少妇人妻久久久久久| 久久人妻少妇嫩草AV蜜桃| 久久99国产精品久久久| 亚洲精品午夜国产VA久久成人|