• <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

             

            每個軟件開發者必須絕對至少需要了解的Unicode和Character Sets的知識(沒有借口!)

            http://blog.csdn.net/natsu1211/article/details/8518398

            每個軟件開發者必須絕對至少需要了解的Unicode和Character Sets的知識(沒有借口!)

             

            原文:http://www.joelonsoftware.com/articles/Unicode.html

             

            by Joel Spolsky

            windam

             

            2003.10.8 星期三

            你是否曾經對那個神秘的Content-Type標記感到不解?

            譯注:每個HTML頁面的head塊中都可能包含一個Content-Type標記,例如:

            <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />

            你知道這東西應該被放到HTML里,但是你從來都沒有確切得弄清楚它到底應該是什么?

             

            你是否曾經收到過你朋友從Bulgaria發來的Email,它的主題行是“???? ?????? ??? ????”?

             

            當我發現還有那么多的軟件開發者并沒有真正領會關于字符集(Character sets),編碼(encoding),Unicode以及相關知識的時候,我非常失望。幾年前,FogBUGZ的一個beta測試者對于它是否能處理收到的日語郵件感到疑惑。日語?他們有日文的Email?我不知道。但當我仔細研究我們用來解析MIME email的商業ActiveX控件時,我們發現它恰恰正好對字符集做了完全錯誤的處理,于 是,為了撤銷控件中所做的錯誤轉換,并正確的重新處理,我們不得不編寫修正它的補救代碼。而當我研究另一個商業庫的時候,發現它有一樣的完全錯誤的字符代 碼實現。我和那個代碼庫的開發者通信,發現他的想法是,他們“不能(對字符集)做任何事(正確的處理)”。就像很多程序員一樣,他只是祈禱著,這一切麻煩 事都可以被吹走。

             

            但事實上不會!當我發現流行的web開發語言PHP幾乎完全的忽略了字符編碼的問題,沒心沒肺的用了8bit字符,這種傻逼的行為讓開發好的國際化web應用變得幾乎不可能的時候,我想,我受夠了。

             

            我在此聲明:如果你是一個工作在2003年或之后的程序員(此文寫于2003年10月),并且你還沒有對字符,字符集,編碼和Unicode有所了解,而且你被我我抓住了,我會罰你在潛艇里剝6個月的洋蔥皮!我發誓我會這樣做的!

             

            此外還有一事:

             

            這真的沒那么難

             

            在本文中,我將會告訴你每個在工作中的程序員所應知道的。所有關于“plain text = ascii = character就是8bit”的知識不僅僅是錯誤的,而且是錯得令人絕望。如果你依然像這樣編程,那么你真不比一個不信基因的醫生好到哪里去。在讀完本文之前,請不要再編寫任何一行代碼!

             

            在我開始之前,我應該提醒你,如果你是那些少數懂得國 際化的知識的程序員,那么你會發現我討論的整個話題有那么一點過于簡化。我僅僅只是希望在此設立一個門檻,使得每個人都理解關于字符編碼究竟都發生了些什 么事情,并有希望使寫出的代碼可以在任意語言下正常工作,而非僅僅只能工作在在不帶方言詞匯的英語環境中。我還要再提醒你,想創建可以在國際化語言環境下 工作的軟件,字符處理僅僅只是很小的一部分工作,但是我一次只能寫一個主題,所以本文就是關于字符集的。

             

            從歷史的角度

             

            理解一件事情的最簡單的方法,就是回到它發生的時候去。

             

            你可能以為我要在此談論那些非常老舊的字符集如EBCDIC。嘛,我們不討論那些。EBCDIC和你的生活沒有關聯。我們不需要走到那么遠古的時期。

             

            clip_image002[13]回到再近一點的時間,當Unix被發明,K&R正在寫那本著名的The C Programming Language的時候,一切都還很簡單。EBCDIC正逐漸消亡。那時唯一有意義的就是那些美好的,不包含方言字符的英文字母。于是我們將這套將每一個字符通過32到127之間的數進行表示的編碼,記做ASCII。例如,空格是32, 字母“A”是65。這些字符用7個bit就可以存儲。那個年代的電腦多數采用8bit為一字節,因此你不光可以用7個bit保存每個可能的ASCII字 符,你還有一個bit的空余,如果你夠邪惡,你也可以將之用于自己的狡猾目的:WordStar用了一個很2B的做法——用最高位來標識一個單詞的最后一 個字母,這宣告了WordStar僅能用于英文文本。比32小的編碼被稱為不可打印字符,并且被用來釋放詛咒——只是開個玩笑,實際上它們是控制字符,比 如7可以讓你的電腦發出蜂鳴聲,12可以讓當前頁紙被送出打印機并傳入新紙。

             

            如果你只是一個英語使用者的話,這一切都很美好。

             

            因為一個字節有8個比特,于是很多人就想,“哎,我們可以使用128-255作為自己的用途”。不過麻煩在于,很多人同時有了這個想法,并且他們關于如何使用128~255的想法又各不相同。IBM-PC弄出來一個被稱為OEM字符集的玩意,為歐洲的語言提供了一些方言字母,以及一串用來繪制線條的字符如水平條,豎直條,右側帶有小的拐角的水平條等。這樣,你就可以使用這些畫線字符,在屏幕上繪制整潔漂亮的方框與線條了。你至今依然可以在那些那些運行于8088計算機的干洗機上看到這些字符。事實上,當除美國之外的人們開始購買PC時,人們憑空捏造出各種各樣的OEM字符集,都將高128位用于自己的用途。舉例來說,在一些PC上,字符碼130被顯示為é,而在以色列銷售的計算機,這個字符碼則顯示為希伯來字母(clip_image004[32]) ,于是,如果美國人將他們的résumés(簡歷)發送到以色列,這簡歷在到達后就變成了rclip_image004[33]sumclip_image004[34]s。在很多場合,比如俄語中,關于如何使用高128位字符有各種各樣的辦法,因此你甚至無法可靠的交換俄語文檔。

             

            最終,這種混亂無序的OEM編碼被ANSI標準統一了。在ANSI標準中,所有人都同意對低128的定義,與ASCII碼保持一致,高128位編碼的處理方式,則取決于你生活在什么地方。這些對高128位編碼做不同處理的體系被稱為code pages(代碼頁)。所以,例如以色列的DOS使用 的代碼頁被稱為862,而希臘的用戶使用的代碼頁是737。這些不同代碼頁在128以下的部分都是相同的,而對于128以上的編碼則有不同的處理方案(那 些搞笑的字母皆被含在其中)。MS-DOS的國家版本中包含了很多上述這種代碼頁,可以處理從英語到冰島語的一切,他們甚至還包括了少數“多語言”代碼 頁,可以在一臺電腦上同時支持世界語和加利西亞語!WOW!但是話說回來,由于希伯來語和希臘語分屬不同的代碼頁,對大于128的字符有完全不同的解釋,因此除非使用位圖,否則想在一臺電腦上同時支持這兩種語言則是一件完全不可能的任務。

             

            另一方面,在亞洲,事情則更加令人抓狂了,因為亞洲的許多語言擁有數以千記的字符,這是無論如何不可能用8 個bit進行編碼的。這種情況通常是用“DBCS”的方式進行解決,也即雙字節字符集,在雙字節字符集中,有的字符使用一個字節進行表示,而有的則需要存 儲在2個字節中。這種字符集的問題在于,通常想要在字符串中順序遍歷比較容易,但是要想反向遍歷,則幾乎不可能。對于這類字符串,程序員們最好不要使用 s++或者s–對其進行遍歷,而是最好使用預定義的函數,例如Windows平臺上的AnsiNext和AnsiPrev函數,它們知道如何處理這一切亂 七八糟的麻煩事。

             

            但是,絕大多數人依然以為一個字節就恰好對應著一個字 母,或是一個字母就是一個字節。只要你永遠不把一個字符串從一臺電腦上拷貝到另一臺電腦上,或者從來不使用超過一種語言,這種做法就可以在某種意義上正常 的工作。但是,理所當然的,由于因特網的普及,現在將字符串從一臺電腦拷貝到另一臺電腦變得越來越常見,那么這一切做法的基礎就垮臺了。幸運的是,Unicode被發明了。

             

            Unicode

             

            針對人們想要創建一個可以囊括這顆星球上一切可能的書寫系統的字符集的目標,Unicode 是一次勇敢的嘗試。一些人以為Unicode只是一個簡單的16bit編碼,其中的每個字符都可以擁有16個bit,因而可以支持最多65536種可能的字符,這種對Unicode的認識,事實上,是錯誤的。這是針對Unicode流傳得最廣的一種誤解,所以,如果你也是這樣認為的,不用覺得過于沮喪。

             

            事實上,Unicode針對字符有一套完全不同的思路,因此你必須遵循Unicode看待事物的思維模式,否則你什么都理解不了。

             

            直到現在,我們都認為一個字母可以被映射為若干比特,你可以將之存儲于內存中或者磁盤上。

             

            例如 A -> 0100 0001

             

            Unicode中,一個字母被映射到一個稱為code point的東西,這只是一個理論上的抽象概念。至于這個code point如何在內存中表示,或是在磁盤中存儲,則又是另一回事了。

             

            Unicode中,字母A是抽象的形象。它在天堂中漂浮著:

             

            A

            這個抽象的Unicode中的A不同于B,且不同于a。但是與A或者A以 及A都是等同的。關鍵的地方在于,Times New Roman字體中的A與Helvetica字體中的A是相同的字符,而與小寫的“a”是不同的字符。這看起來并沒有什么有所疑議的,但是在某些語言中,僅 僅指出一個字母是什么就可能引發疑議。德文字母ß究竟是一個真實的字母,還是僅僅只是s的另一種花式寫法?如果一個單詞末尾的字母的形狀改變了,那么這個 字母是否意味著一個不同的字母——請作答?在希伯來文中,上面這個問題的回答為真,而在阿拉伯語中,則為假。無論如何,Unicode協會的那些聰明人們 已經在上一個十年間把這些東西都搞定了,盡管那其中依然包含了一大堆政治上的討價還價,但是最終的結果是,你不用再為這些麻煩事而煩神了——他們把這些玩 意都搞定了。

             

            Unicode協會為每一個字母表中的每一個抽象字母都賦予了一個Magic number,寫起來就像是這樣:U+0639。這個Magic number(魔數)就被稱為code point。其中的U+意味著“Unicode”,而數字的部分則是16進制的(譯注:4位16進制數也就意味著需要16個bit的存儲空間)。那么U+0639實際上就是阿拉伯字母Ain。英文字母A則是U+0041。你可以在Windows 2000/XP(譯注:在Vista or Win7上也可)使用charmap實用工具來查詢這些code point(譯注:點擊開始菜單,運行,輸入charmap回車啟動該工具),也可以通過訪問Unicode的網站查詢。

             

            clip_image006[13]

            (譯補圖:這是charmap實用工具的運行界面,其中英文字母A如圖所示恰為U+0041)

             

            并沒有人真正對Unicode所能表示字母數目上限進行限制,事實上,Unicode所能表示的字母數目可以超過65536,所以并不是每一個Unicode字母都可以被塞進2字節的空間中,不過這只是個傳聞。

             

            OK,假設我們有這樣一個字符串

             

            Hello

            Unicode中,這被表示為以下五個code point:

             

            U+0047  U+0065  U+006C  U+006C  U+006F.

             

            只是一組code point。事實上,也就是數字。到目前為止,我們還沒有提到過如何在內存中存儲它們,或是在email中如何表示它們。

             

            Encodings

             

            這就是encodings (編碼)發揮作用的地方了。

             

            關于Unicode編碼的最早的主意是這樣的,嘿伙計,咱們把這些數字每個存成2字節吧。(這個主意也正是2字節神話的淵源)于是,我們的Helllo就變成了下面這樣:

             

            00 48 00 65 00 6C 00 6C 00 6F

             

            對嗎?別著急!為什么不能是下面這樣呢:

             

            48 00 65 00 6C 00 6C 00 6F 00

             

            好吧,從技術上說,這樣也可以,我確實這么認為,而事實上,由于早期的實現者們在他們要存儲Unicode code point的時候,希望依據特定的CPU架構選擇是使用大端(high-endian)還是小端(low-endian)模式,這樣使得CPU處理速度得 以最佳化。于是,看哪,很快的,就出現了兩種不同的存儲Unicode的方式。于是人們不得不創造一個離奇的約定,在Unicode的字符串的最前面加上 一個FE FF標識符。這個標識符被稱為Unicode Byte Order Mark(Unicode字節序標識符),并且,如果你反轉了你的高低字節,那么這個標識符就會變成FF FE,于是讀取你的字符串的人就可以知道他們必須要翻轉你的每一對高低字節。但是,喔,并不是每一個Unicode字符串都在開頭有這個字節序標識符。

             

            一開始,這一切看起來似乎還是挺好的,但是逐漸的,程序員們開始抱怨,“看那一堆沒用的0!” ——由于這些美國程序員多數情況下只使用英文文本,也就意味著他們幾乎不會用到那些高于U+00FF的code point。尤其是他們多數還是加州的新自由主義嬉皮士,假若他們是德州人,那么他們多半不會在意這些多出來的字節。但是最終,這幫加州的苦孩子們終于無 法容忍字符串存儲空間被無端的增長一倍,并且,由于有那么多的文檔已經用各種ANSI和DBCS字符集存在了,誰會把這些文檔都轉換到Unicode下來 呢?難道是我(法語)來?僅僅因為這樣的想法,于是在好幾年的時間里,大多數人都決定無視Unicode,這使得事情變得更糟。

             

            終于,一個天才的概念被發明出來了——UTF-8UTF-8在內存中通過8bit的字節來保存U + magic number,定義了保存Unicode字符串的一整套系統。在UTF-8中,0-127之間的code point被保存在一個單字節中。只有那些大于等于128的code point,需要用到2,3以及多至6個字節來保存。

             

            clip_image008[14]

             

            這種做法獲得了一個非常不錯的副作用——那就是UTF-8中的英文文本與ASCII中的英文文本可以完全的保持一致,于是美國人們都不會發現有什么事情變得不一樣了。只有這世界上其他地方的人們不得不跳過這個坑。舉例來說,Hello, 這個字符串由code point:U+0048 U+0065 U+006C U+006C U+006F組成,在存儲的時候,被保存為48 65 6C 6C 6F,這,恰恰正好與ASCII,ANSI,以及這顆星球上所有的OEM字符集中的表示都完全一樣。現在,如果你需要去使用方言字母,或者是希臘字母,或 者是克林貢語字母的話,那么你就不得不為每個code point使用多個字節去存儲了,不過美國人永遠都不用在意這些了。(UTF-8還有一個非常漂亮的特性,以往的Unicode字符串想使用老式的以單個 byte的0作為字符串的結尾并不至于切斷字符串的話需要一些處理代碼,而UTF-8則可以忽略之。)

             

            到目前為止,我已經告訴了你Unicode 編碼的三種方法。最傳統的兩字節存儲方式被稱為UCS-2(因為有2個字節)或者UTF-16(因為有16個Bit),并且你還得自己弄清楚究竟這是一個 大端(High-endian)UCS-2還是一個小端(low-endian)UCS-2。你還可以采用全新的UTF-8標準,如果你只使用英文文本, 它會讓你在碰到一個無腦程序時,即便它完全無視了除ACSII之外的一切,你依然會過得很幸福!

             

            事實上還有其他一系列方法來編碼Unicode。 有一種編碼叫做UTF-7,它與UTF-8有很多相似之處,但是它假定所有字節的最高比特都是0。因為這個原因,如果你要把Unicode字符串傳遞給一 個嚴格認為7bit就足夠用的警方郵件系統,那么感謝UTF-7吧,它能使你免于痛苦。還有種UCS-4編碼,它使用4個字節存儲一個code point,它有個不錯的特性,每個code point都是等長的,但是麻煩在于,它是在浪費了太多的內存,以至于即便是得克薩斯人也不敢使用它。

             

            事實上你正在使用Unicode code point所表示的柏拉圖式的理想的字母來考慮這些問題,這些Unicode code point同樣也可以使用任何一種舊的學院派的編碼方案來表示。舉例而言,你同樣可以用ASCII或古希臘OEM編碼或希伯來ANSI編碼,乃至迄今為止 已被發明的數百種編碼,來表示一個Unicode編碼的字符串Hello(U+0048 U+0065 U+006C U+006C U+006F)。但是這些做法有一個陷阱,那就是某些字母可能不能正常顯示!如果你想要將某個Unicode code point在某種編碼中表示,而該編碼中又沒有能對應上該code point的,你常常會得到一些小的問號:?或者,如果你的人品不錯,你會得到一個?

             

            存在數以百計的傳統編碼,它們都只能正確表示Unicode code point的某些子集,而對那些處理不了的code point,則用問號來處理。有一些流行的英文編碼,諸如Windows-1252(這是Windows 9x中的西歐語言標準),以及ISO-8859-1aka Latin-1(同樣在任何一個西歐語言中都會有用的),如果你想要用上面這些編碼來處理俄文或者是希伯來字母,那么你會得到大量的問號。與之對應的,UTF7,8,16以及32等編碼則有非常棒的特性,它們可以正確表示任何Unicode code point

             

            關于編碼的最重要的事實

             

            如果你把我之前所解釋的所有一切都忘光了,請你至少記住一個最最最重要的事實。如果你有一個字符串,而不知道它的編碼,那么這個字符串是毫無意義的。你再也不能把腦袋埋到沙子里,然后假裝“普通”文本就是ASCII。

             

            這世界上就沒有普通文本這回事。

             

            如果你有一個字符串,不管是在內存里,還是在文件里,還是在一封email中,你必須知道它的確切的編碼,否則你不可能做到正確的解釋它,或是向用戶顯示。

             

            幾乎所有的像是“我的網站看起來像是在胡言亂語”,或者是“如果我在郵件里用了方言字母,那么她就無法閱讀”的傻逼問題,幾乎都是由于某些天真犯二的程序員沒能理解下面這個事實:如果你不告訴我一個特定的字符串用的是哪一種編碼,UTF-8或是ASCII或是ISO 8859-1(Latin 1)或是Windows 1252(西歐),那么我就不可能正確的顯示這個字符串,甚至不可能知道哪里是它的結尾。有上百種編碼格式的存在,并且一旦出現大于127的code point,那么一切就全完了。

             

            一個字符串是如何編碼的,我們要如何維護這樣一個信息呢?好吧,關于這件事情,有一些標準做法。對于email消息,你最好在正文的頭部,加入這樣一行字符串:

             

            Content-Type: text/plain; charset=”UTF-8″

             

            對于網頁頁面,最早的想法是由web服務器返回一個類似的Content-Type,把這個信息放在與網頁內容一同傳輸的HTTP報頭中,不是放在HTML頁面里,而是放在響應報頭里,在HTML內容之前被發送。

             

            但這種做法會導致問題。想象一下你有一個巨大的web 服務器,上面跑著很多網站,并且有著由不同的人貢獻的數以百計的網頁。這些人創建網頁的時候,他們所使用的Microsoft FrontPage可能以任何它覺得合適的方式來選擇編碼進行存儲。web服務器本身對此一無所知,它不可能知道每一個文件是以什么編碼格式寫的,所以它 也就無法為之發送Content-Type頭。

             

            如果你使用某種特殊的tag,把 HTML文件所使用的Content-Type直接寫到HTML文件里,就會讓后續的事情變得更加方便。當然這種做法會讓某些純化論者感到抓狂…如果你不 知道這個HTML文件的編碼,你要如何去讀取它?!幸運的是,幾乎所有的編碼對32到127之間的字符都是同樣對待的,于是,在需要使用任何詭異的字母之 前,你總是可以在HTML頁面中讀取到至少像下面這樣多的內容:

             

            <html>

            <head>

            <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

             

            但是需要注意的是,這個meta tag必須是<head>節中最先出現的東西。因為只要網頁瀏覽器見到這個tag,它就會停止解析這個頁面,并且使用你所指定的編碼開始重新解釋整個頁面。

             

            如果網頁瀏覽器即無法從http報頭也 無法從HTML的meta標記中找到任何Content-Type信息,那么它們會如何對待這個網頁呢?事實上,Internet Explorer做了一些有趣的事情,它基于一種啟發式的方法去猜(依照典型編碼的典型文本中,各種不同的語言使其字節呈現不同的分布頻率的規律)。因為 各種舊的8bit代碼頁會嘗試把他們國家的字母放在128~255中不同的區間段里,同時又由于每一種人類語言對字母的使用都呈現不同的統計特征,所以上 述方案,有一定的概率是可以工作的。這做法是很怪異的,這使得那些天真無邪的網頁作者,在從來不知道每個HTML頁面都需要一個Content-Type 頭的情況下繼續寫網頁,并且當他們在瀏覽器中查看時,發現一切都是正常的。直到有一天,他們寫了點東西,與他們母語中的字母頻率分布不相符合,于是 Internet Explorer便認為這是一段韓語,然后,就這么繼續顯示出來……我相信,這證明了Postel法則中所說的,“寬容的對待輸入,而保守的輸出”,坦白說并不是一個好的工程原則。無論如何,當這個網站的可憐的讀者,在面對這個被顯示成韓語(并且事實上是根本無法理解的韓語)而事實上是保加利亞語的網頁時,要怎么做呢?他使用View|Encoding菜單,并且依次嘗試每一個編碼的選項(至少有十數個東歐語言選項),直到一切變得正常。但是,事實上,多數人都不知道要這么做。

             

            clip_image009[13]

             

            我公司所發布的網站管理軟件CityDesk的最新版本中,我們決定內部的一切都用UCS-2(2字節)Unicode表示,這也是Visual Basic,COM以及Windows NT/2000/XP所使用的原生的字符串類型。

             

            C++代碼中,這意味著當定義字符串時,我們使用wchar_t(寬字符)來替代char,并且使用wcs系函數來替代str系函數(例如,使用wcscatwcslen而不是strcatstrlen)。要在C代碼中創建一個UCS-2的字符串,你只需要在字符串定義前增加一個L,如:L”Hello”

             

            CityDesk發布網頁時,它將之轉換為已經為網頁瀏覽器所支持多年的UTF-8編碼格式。這也是Joel on Software全部29種語言版本所使用的編碼,并且我從來沒有聽到過任何一個人抱怨說在閱讀它的時候遇到麻煩。

             

            本文的篇幅有點長,并且我也不可能覆蓋關于Unicode和字符編碼的所有話題,我希望的是,如果你已經閱讀到這里,你已經知道了足夠多的知識,我留給你的任務,就是回去編寫程序,并且記得在對付疾病的時候使用抗生素,而不是水蛭和魔咒。

             

            還想知道更多?你現在閱讀的是Joel on Software,這里填滿了各種經年累月積累下來的關于軟件開發,管理軟件團隊,設計用戶界面,成功運營一家軟件公司,以及橡皮鴨的各種胡言亂語的文章。

             

            關于作者:我 是Joel Spolsky,Fog Creek Software的共同創始人,Fog Creek Software是一家紐約的公司,它證明了你可以在對待程序員們很好的同時創造出很高的利潤。這里的程序員擁有私人的辦公室,免費的午餐,以及每周40 個小時的工作時間。公司的客戶只為他們滿意的軟件付費。我們創造了一個更先進的bug跟蹤軟件FogBugz,以及軟件開發工具。Kiln,一個分布式的源代碼管理系統,如果你迷戀svn,它會讓你非常驚喜,以及Fog Creek Copilot,可以讓訪問遠程桌面變得更加容易。我同時也是Stack Overflow的共同創始人。

             

             

            譯注:本文對Unicode和編碼的解釋非常棒,將編碼和字符集的來龍去脈解釋得深入淺出,是每個合格的程序員所必知必會的基礎知識,本人在閱讀《Game Engine Architecture》一書時,了解到此文,遂生出翻譯的興趣,翻譯的過程中確又發現再次理清了若干此前未曾真正理解的概念,只因英文水平和精力有限,難免有所錯漏,如有指正,不吝感激。

            posted @ 2013-06-22 15:47 多彩人生 閱讀(2976) | 評論 (2)編輯 收藏

            gregorian::greg_month::get_month_map_ptr()

            Error: undefined reference to 'boost::gregorian::greg_month::get_month_map_ptr() '

            g++ -L/usr/lib -lboost_date_time

             

            note: should install boost_date_time in Ubuntu.

            posted @ 2013-06-15 14:24 多彩人生 閱讀(831) | 評論 (0)編輯 收藏

            defy

            http://www.itopdog.cn/android/defy-root-rom.html

            posted @ 2013-06-15 00:20 多彩人生 閱讀(147) | 評論 (0)編輯 收藏

            正確使用stl map的erase方法

            http://www.cnblogs.com/kex1n/archive/2011/12/06/2278505.html

            先聲明:下面的文章是針對windows的用法,因為std::map的erase函數的windows的實現版本是返回一個std::map的迭代器,但是STL標準里面的該函數的返回值確是:

            map.erase有3個重載:
            void erase ( iterator position );
            size_type erase ( const key_type& x );
            void erase ( iterator first, iterator last );

            所以下面的代碼中的最后一個例子僅僅可以在windows下的map下運行。

             

            STL的map表里有一個erase方法用來從一個map中刪除掉指令的節點
            eg1:

            map<string,string> mapTest;
            typedef map<string,string>::iterator ITER;

            ITER iter=mapTest.find(key);
            mapTest.erase(iter);

             像上面這樣只是刪除單個節點,map的形為不會出現任務問題,
            但是當在一個循環里用的時候,往往會被誤用,那是因為使用者沒有正確理解iterator的概念.
            像下面這樣的一個例子就是錯誤的寫法,
            eg2:

            for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)
            {
            cout<<iter->first<<":"<<iter->second<<endl;
            mapTest.erase(iter);
            }

            這是一種錯誤的寫法,會導致程序行為不可知.究其原因是map 是關聯容器,對于關聯容器來說,如果某一個元素已經被刪除,那么其對應的迭代器就失效了,不應該再被使用;否則會導致程序無定義的行為。
            可以用以下方法解決這問題:
            正確的寫法
            1.使用刪除之前的迭代器定位下一個元素。STL建議的使用方式

            for(ITER iter=mapTest.begin();iter!=mapTest.end();)
            {
            cout<<iter->first<<":"<<iter->second<<endl;
            mapTest.erase(iter++);
            }

            2. erase() 成員函數返回下一個元素的迭代器

            for(ITER iter=mapTest.begin();iter!=mapTest.end();)
            {
            cout<<iter->first<<":"<<iter->second<<endl;
            iter=mapTest.erase(iter);
            }

            posted @ 2013-05-30 16:51 多彩人生 閱讀(294) | 評論 (0)編輯 收藏

            cocos2d-x

            http://www.cnblogs.com/graphicsme/archive/2012/11/06/2756914.html

            http://www.lvcoffee.info/archives/date/2013/03
            http://www.cnblogs.com/klobohyz/archive/2012/08/01/2617794.html

            posted @ 2013-05-28 22:15 多彩人生 閱讀(215) | 評論 (0)編輯 收藏

            mangos

            http://www.cnblogs.com/ychellboy/archive/2012/02/10/2345879.html
            http://blog.csdn.net/lixinso/article/details/4694921

            posted @ 2013-05-24 17:04 多彩人生 閱讀(277) | 評論 (0)編輯 收藏

            Vim 配置詳解

            http://www.cnblogs.com/witcxc/archive/2011/12/28/2304704.html
            http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html
            http://www.thegeekstuff.com/2009/01/tutorial-make-vim-as-your-cc-ide-using-cvim-plugin/

            posted @ 2013-05-24 08:57 多彩人生 閱讀(189) | 評論 (0)編輯 收藏

            lua fPIC error

            安裝lua

            tar zxvf lua-5.1.4.tar.gz

            cd lua-5.1.4

            如果你的服務器是64位的,這時要調整一下Makefile:vi src/Makefile,在CFLAGS里加上-fPIC,否則會出錯:

            /usr/bin/ld: /usr/local/lib/liblua.a(lapi.o):

            relocation R_X86_64_32 against `luaO_nilobject_' can not be used when making a shared object;

            recompile with -fPIC

            /usr/local/lib/liblua.a: could not read symbols: Bad value

            接下來不用執行常見的configure,直接make:

            make linux

            make install

            posted @ 2013-04-23 14:50 多彩人生 閱讀(1606) | 評論 (0)編輯 收藏

            pg_ctl

            pg_ctl
            名稱
            pg_ctl -- 啟動、停止、重啟 PostgreSQL
            語法
            pg_ctl start [-w] [-s] [-D datadir] [-l filename] [-o options] [-p path]
            pg_ctl stop [-W] [-s] [-D datadir] [-m s[mart] | f[ast] | i[mmediate] ]
            pg_ctl restart [-w] [-s] [-D datadir] [-m s[mart] | f[ast] | i[mmediate] ] [-o options]
            pg_ctl reload [-s] [-D datadir]
            pg_ctl status [-D datadir]
            pg_ctl kill [signal_name] [process_id]
            pg_ctl register [-N servicename] [-U username] [-P password] [-D datadir] [-w] [-o options]
            pg_ctl unregister [-N servicename]

            描述
            pg_ctl 用于啟動、停止、重啟 PostgreSQL 后端服務器(postgres),或者顯示一個運行著的服務器的狀態。盡管可以手動啟動服務器,但是 pg_ctl 封裝了重新定向日志輸出,與終端和進程組合理分離,以及另外提供了一個選項用于有控制的關閉。

            在 start 模式里會啟動一個新的服務器。服務器是在后臺啟動的,標準輸入被附著到了 /dev/null 上。如果使用了 -l ,那么標準輸出和標準錯誤將被定向到一個日志文件,要么就是重定向到 pg_ctl 的標準輸出(而不是標準錯誤)。如果沒有選定日志文件,pg_ctl 的標準輸出應該重定向到一個文件或者用管道輸出到類似 rotatelogs 這樣的日志滾動程序,否則,postgres 將把它的輸出寫到控制終端(在后臺)并且將不會脫離 shell 的進程組。

            在 stop 模式下,那個正在特定數據目錄運行的服務器將被關閉。你可以用 -m 選項選擇三種不同的關閉模式:"Smart"模式等待所有客戶端中斷連接,這是缺省。"Fast"模式并不等待客戶端中斷連接,所有活躍事務都被回滾并且客戶端都被強制斷開。"Immediate"模式將在沒有干凈關閉的情況下強行退出。這么做將導致在重新啟動的時候的恢復。

            restart 實際上是先執行一個停止,然后緊跟一個啟動。它允許變換 postgres 的命令行選項。

            reload 模式簡單地給 postgres 發送一個 SIGHUP 信號,導致它重新讀取配置文件(postgresql.conf, pg_hba.conf 等),這樣就允許修改配置文件選項而不用重啟系統即可生效。

            status 模式監查一個服務器是否在指定的數據目錄運行,如果是,那么顯示其 PID 和調用它的命令行選項。

            kill 模式允許你給一個指定的進程發送信號。這個功能對 Microsoft Windows 特別有用,因為它沒有 kill 命令。使用 --help 查看支持的信號名字列表。

            register 模式允許你在 Microsoft Windows 上注冊一個系統服務。

            unregister 模式允許你在 Microsoft Windows 上刪除先前用 register 命令注冊的系統服務。

            選項
            -D datadir
            聲明該數據庫的文件系統位置。如果忽略則使用 PGDATA 環境變量。

            -l filename
            把服務器日志輸出附加在 filename 文件上。如果該文件不存在則創建它。umask 設置為 077 ,因此缺省時是不允許從其它用戶向日志文件訪問的。

            -m mode
            聲明關閉模式。mode 可以是 smart, fast, immediate 之一,或者是這三個的首字母之一。

            -o options
            聲明要直接傳遞給 postgres 的選項。

            參數通常都用單或者雙引號包圍以保證它們作為一個整體傳遞。

            -p path
            聲明 postgres 可執行文件的位置。缺省位于 pg_ctl 自身所在目錄,如果沒找到則使用硬編碼的安裝目錄。除非你想干點什么特別的事情,并且想得到類似沒有找到 postgres 這樣的錯誤,否則必須使用這個選項。

            -s
            只打印錯誤,而不打印提示性信息。

            -w
            等待啟動或者關閉的完成(60 秒超時),這個參數是關閉時的缺省值。成功的關閉是以刪除 PID 文件為標志的。對于啟動而言,一次成功的 psql -l 就標志著成功。pg_ctl 將企圖使用對 psql 合適的端口,如果存在 PGPORT 環境變量,那么將用它。否則,它將查找在 postgresql.conf 文件里是否設置了一個端口。如果都沒有,它將使用 PostgreSQL 編譯時的缺省端口(缺省 5432)。在等待的時候,pg_ctl 將根據啟動或者關閉的成功狀況返回一個準確的退出代碼。

            -W
            不等待啟動或者停止的完成。這是啟動和重啟的缺省。

            Windows 選項
            -N servicename
            要注冊的系統服務的名字。這個名字將用于服務名和顯示名。

            -P password
            用戶啟動服務的口令

            -U username
            用于啟動服務的用戶的用戶名。對于域用戶,使用 DOMAIN\username 格式。

            環境變量
            PGDATA
            缺省數據目錄位置

            PGPORT
            psql 的缺省端口(由 -w 選項使用)。

            其它的環境變量請參閱 postgres

            文件
            postmaster.pid
            這個文件存在于數據目錄中是為了幫助 pg_ctl 判斷服務器當前是否在運行。

            postmaster.opts.default
            如果這個文件存在于數據目錄,pg_ctl (在 start 模式下)將把文件地內容當作傳遞給 postgres 命令的選項傳遞過去,除非被 -o 選項覆蓋。

            postmaster.opts
            如果這個文件存在于數據目錄,pg_ctl (在 start 模式下)將把文件地內容當作傳遞給 postgres 命令的選項傳遞過去,除非被 -o 選項覆蓋。這個文件的內容也會在 status 模式里顯示出來。

            postgresql.conf
            這個文件在數據目錄中,會分析它以查找和 psql 一起用的合適的端口(在 start 模式里給出 -w 的時候)。

            注意
            等待完全啟動還不是一個定義得很完整的操作,如果訪問控制設置為本地客戶端在沒有手工交互的情況下不能訪問的話還可能會失效(比如口令認證)。

            例子
            啟動服務器
            啟動服務器:

            $ pg_ctl start啟動服務器的一個例子,等到服務器啟動了才退出:

            $ pg_ctl -w start服務器使用 5433 端口,而且不帶 fsync 運行,使用:

            $ pg_ctl -o "-F -p 5433" start停止服務器
            $ pg_ctl stop使用 -m 選項停止服務器允許用戶控制如何關閉后端。

            重啟服務器
            這個命令幾乎等于先停止服務器然后再啟動它,只不過 pg_ctl 保存并重新使用上一次運行服務器的命令行參數。重啟服務器的最簡單的方法是:

            $ pg_ctl restart重啟服務器,等待其停止和重啟:

            $ pg_ctl -w restart使用 5433 端口重啟并且重啟后關閉 fsync :

            $ pg_ctl -o "-F -p 5433" restart顯示服務器狀態
            下面是來自 pg_ctl 的狀態輸出的例子:

            $ pg_ctl statuspg_ctl: server is running (pid: 13718)Command line was:/usr/local/pgsql/bin/postgres '-D' '/usr/local/pgsql/data' '-p' '5433' '-B' '128'這就是在 restart 模式中被調用的命令行。

            又見
            postgres

            pg_resetxlog
            名稱
            pg_resetxlog -- 重置一個數據庫集群的預寫日志以及其它控制內容
            語法
            pg_resetxlog [-f] [-n] [-ooid ] [-x xid ] [-e xid_epoch ] [-m mxid ] [-O mxoff ] [-l timelineid, fileid, seg ] datadir

            描述
            pg_resetxlog 清理預寫日志(WAL)并且可以有選擇地重置其它一些存儲在 pg_control 文件中的控制信息。有時候,如果這些文件崩潰了,就需要這個功能。一定只把它用作最后的方法,就是說只有因為這樣的崩潰導致服務器無法啟動的時候才使用。

            運行這個命令之后,可能就可以啟動服務器了,但是,一定要記住數據庫可能因為部分提交的事務而含有不完整的數據。你應該馬上轉儲數據,運行 initdb ,然后重新加載。在重新加載之后,檢查不完整的部分然后根據需要進行修復。

            這個命令只能由安裝服務器的用戶運行,因為它需要對數據目錄的讀寫權限。出于安全考慮,pg_resetxlog 不使用環境變量 PGDATA ,你必須在命令行上聲明數據目錄。

            如果 pg_resetxlog 抱怨說它無法判斷用于 pg_control 的有效數據,那么你可以強制它繼續處理,方法是聲明 -f(強制)開關。在這種情況下,那些丟失了的數據將用模糊的近似數值代替。大多數字段都可以匹配上,但是下一個 OID 、下一個事務 ID 、下一個事務 ID 的 epoch(時間點)、下一個多事務 ID(兩階段提交的東西)、下一個多事務偏移量、WAL 開始地址、數據庫區域字段可能需要手工幫助,前面六個可以用下面討論的開關設置。pg_resetxlog 自己的環境是猜測區域字段的來源;看看 LANG 等東西,它們應該和 initdb 運行的環境相匹配。如果你不能判斷所有這些字段的正確數值,那么 -f 仍然可以使用,但是這樣恢復過來的數據庫正確性更值得懷疑:立即轉儲和重新加載是必須的。在轉儲之前不要執行任何修改數據的操作,因為任何這樣的動作都可能把事情搞得更糟糕。

            -o, -x, -e, -m, -O, -l 開關允許手工設置下一個 OID 、下一個事務 ID 、下一個事務 ID epoch 、下一個多事務 ID 、下一個多事務偏移量、WAL 起始位置的數值。只有在 pg_resetxlog 無法通過讀取 pg_control 判斷合適的數值的時候才需要它。安全的數值可以用下面的方法判斷:

            對于下一個事務 ID(-x)而言,一個安全的數值是看看數據目錄里的 pg_clog 里數值最大的文件名,然后加一,然后再乘上 1048576 。請注意那些文件名是十六進制的。通常也以十六進制的形式聲明開關值是最簡單的。比如,如果 0011 是 pg_clog 里最大的記錄,-x 0x1200000 就可以了(后面的五個零提供了合適的乘積)。

            下一個多事務 ID(-m)的安全值可以通過查看數據目錄里 pg_multixact/offsets 子目錄里面的數字最大的文件名,加一,然后乘以 65536 得到。和上面一樣,文件名是十六進制的,因此最簡單的方法是給開關聲明一個十六進制的開關值,然后在結尾加四個零。

            下一個多事務偏移量(-O)的安全值可以通過檢查數據目錄里 pg_multixact/members 子目錄下的數字最大的文件名,加一,然后乘以 65536 得到。和上面一樣,文件名是十六進制的,因此最簡單的方法是給開關聲明一個十六進制的開關值,然后在結尾加四個零。

            WAL 的起始位置(-l)應該比目前存在于數據目錄 pg_xlog 里面的任何文件號都大。它的文件名也是十六進制的,并且有三部分。第一部分是"時間線 ID",通常應該保持相同。第三部分不要選擇大于 255(0xFF);應該是在達到 255 的時候給第二部分增一然后重置第三部分為 0 。比如,如果 00000001000000320000004A 是 pg_xlog 里最大的條目,那么 -l 0x1,0x32,0x4B 就可以了;但如果最大的條目是 000000010000003A000000FF ,那么選擇 -l 0x1,0x3B,0x0 或更多。

            沒有很容易的辦法來判斷比數據庫中最大的 OID 大一號的下一個 OID ,不過很走運的是獲取正確的下一個 OID 并非非常關鍵的事情。

            除了由 pg_resetxlog 設定的字段外,事務 ID epoch 實際上并未存儲在數據庫里的任何地方。所以只要是涉及到數據庫自身的任何數值都有效。你可能需要調整這個值以確保諸如 Slony-I 之類的備份系統能夠正常工作。如果是這樣的話,應當從下游已復制的數據庫中獲取恰當的值。

            -n(無操作)開關指示 pg_resetxlog 打印從 pg_control 重新構造的數值然后不修改任何值就退出。這主要是一個調試工具,但是在 pg_resetxlog 真正處理前進行的整潔性檢查的時候可能會有用。

            注意
            在服務器運行的時候一定不要運行這個命令。如果發現在數據文件目錄里有鎖文件,那么 pg_resetxlog 將拒絕啟動。如果服務器崩潰,那么可能會剩下一個鎖文件;如果這樣,你可以刪除該鎖文件以便允許 pg_resetxlog 運行。但是在你這么做之前,一定要確保沒有任何后端服務器進程仍在運行。

            postgres
            名稱
            postgres -- PostgreSQL 數據庫服務器
            語法
            postgres [option...]

            描述
            postgres 是 PostgreSQL 數據庫服務器。客戶端應用程序為了訪問數據庫,將通過 TCP Socket 或 Unix domain socket 連接到一個運行中的 postgres 進程。然后該 postgres 實例將啟動(fork)一個新的、獨立的服務器進程來處理這個連接。

            一個 postgres 總是管理來自同一個數據庫集群的數據。一個數據庫集群是一組在同一個文件系統位置("數據區")存放數據的數據庫。一個系統上可以同時運行多個 postgres 進程,只要他們使用不同的數據區和不同的端口號(見下文)。postgres 啟動時需要知道數據區的位置,該位置必須通過 -D 選項或 PGDATA 環境變量指定。通常,-D 或 PGDATA 都直接指向由 initdb 創建的集群目錄。其他可能的文件布局在節17.2里面有討論。

            缺省時 postgres 在前臺啟動并將日志信息輸出到標準錯誤。但在實際應用中,postgres 應當作為后臺進程啟動,而且多數是在系統啟動時自動啟動。

            postgres 還能以單用戶模式運行。這種用法的主要用于 initdb 的初始化過程中。有時候它也被用于調試災難性恢復。不過,單用戶模式運行的服務器并不適合于調試,因為沒有實際的進程間通訊和鎖動作發生。當從 shell 上以單用戶模式調用時,用戶可以輸入查詢,然后結果會在屏幕上以一種更適合開發者閱讀(不適合普通用戶)的格式顯示出來。在單用戶模式下,將把會話用戶 ID 設為 1 并賦予超級用戶權限。該用戶不必實際存在,因此單用戶模式運行的服務器可以用于對某些意外損壞的系統表進行手工恢復。

            選項
            postgres 接受下列命令行參數。關于這些選項的更詳細討論請參考章17。你也可以通過設置一個配置文件來減少敲擊這些選項。有些(安全的)選項還可以從連接過來的客戶端設置,以一種應用無關的方法僅對該會話生效。比如,如果設置了 PGOPTIONS 環境變量,那么基于 libpq 的客戶端就都把那個字符串傳遞給服務器,并被服務器解釋成 postgres 命令行選項。

            通用用途
            -A 0|1
            打開運行時斷言檢查,是檢測編程錯誤的調試幫助。只有在編譯 PostgreSQL 時打開了它,你才能使用它。如果編譯時打開了,缺省是打開。

            -B nbuffers
            為服務器進程分配和管理的共享內存緩沖區數量。這個參數的缺省值是 initdb 自動選擇的;參考節17.4.1獲取更多信息。

            -c name=value
            設置一個命名的運行時參數。PostgreSQL 支持的配置參數在章17里描述。大多數其它命令行選項實際上都是這樣的參數賦值的短形式。-c 可以出現多次從而設置多個參數。

            -d debug-level
            設置調試級別。數值越高,寫到服務器日志的調試輸出越多。取值范圍是 1 到 5 。還可以針對某次單獨的會話使用 -d 0 來防止從父 postgres 進程繼承日志級別。

            -D datadir
            聲明數據目錄或者配置文件的文件系統路徑。細節詳見節17.2。

            -e
            把缺省日期風格設置為"European",也就是說用 DMY 規則解釋日期輸入,并且在一些日期輸出格式里日子在月份前面打印。參閱節8.5獲取更多細節。

            -F
            關閉 fsync 調用以提高性能,但是要冒系統崩潰時數據毀壞的風險。聲明這個選項等效關閉了 fsync 參數。在使用之前閱讀詳細文檔!

            -h hostname
            指定 postgres 偵聽來自前端應用 TCP/IP 連接的 IP 主機名或地址。數值也可以是一個用空格分隔的地址列表,或者 * 表示監聽所有可用的地址。空值表示不監聽任何 IP 地址,而只使用 Unix 域套接字與客戶端通信。缺省只監聽 localhost 。聲明這個選項等效于設置 listen_addresses 配置參數。

            -i
            這個選項允許遠程客戶通過 TCP/IP(網際域套接字)與服務器通訊。沒有這個選項,服務器將只接受本地連接。這個選項等效于在 postgresql.conf 中或者通過 -h 選項將 listen_addresses 設為 *

            這個選項已經廢棄了,因為它不能實現 listen_addresses 的所有功能。所以最好直接設置 listen_addresses

            -k directory
            指定 postgres 偵聽來自前端應用連接的 Unix 域套接字的目錄。缺省通常是 /tmp ,但是可以在編譯的時候修改。

            -l
            這個選項使用 SSL 進行的安全通訊。要使用這個選項,編譯 PostgreSQL 時你必須打開了 SSL 支持。有關使用 SSL 的信息,請參考節16.7。

            -N max-connections
            設置最多允許同時連接多少個客戶端(也就是最多同時運行多少個服務器進程)。缺省值為 32 ,不過該值最大可以設置為系統所能承受的極限。請注意 -B 的值要求至少兩倍于 -N 的值。參閱節16.4獲取有關大量客戶的系統資源需求。聲明這個選項等效于聲明 max_connections 配置參數。

            -o extra-options
            在 extra-options 里面指定的命令行選項將被傳遞給所有由這個 postgres 派生的服務進程。如果選項字符串包含任何空白,那么整個字符串必須用引號界定。

            反對使用該選項,所有服務器進程的命令行選項都可以直接在 postgres 命令行上指定,不必這么麻煩。

            -p port
            指定 postgres 偵聽客戶端連接的 TCP/IP 端口或本地 Unix domain socket 文件的擴展。缺省的端口號是環境變量 PGPORT 的值。如果 PGPORT 沒有設置,那么缺省是 PostgreSQL 編譯時指定的值(通常是 5432)。如果你聲明了一個非缺省端口,那么所有前端應用都必須用命令行選項或者 PGPORT 聲明同一個端口。

            -s
            在每條命令結束時打印時間信息和其它統計信息。這個開關對測試性能和調節緩沖區數量有好處。

            -S work-mem
            聲明內部排序和散列在求助于臨時磁盤文件之前可以使用的內存數量。參閱節17.4.1里描述的配置變量 work_mem

            --name=value
            設置一個命名的運行時參數;其縮寫形式是 -c

            --describe-config
            以制表符分隔的 COPY 格式,導出服務器內部配置變量、描述、缺省值。設計它主要是給管理工具使用。

            半內部選項
            還有幾個其它的選項可以聲明,主要用于調試用途。這些東西在這里列出只是給 PostgreSQL 系統開發人員使用的。強烈反對使用這些選項。另外這些選項的任何一項都可能在未來版本中消失而不加說明。

            -f { s | i | m | n | h }
            禁止某種掃描和連接方法的使用:s 和 i 分別關閉順序和索引掃描,而 n, m, h 分別關閉嵌套循環,融合(merge)和 Hash 連接。

            順序掃描和嵌套循環都不可能完全被關閉。 -fs 和 -fn 選項僅僅是在存在其它方法時阻礙優化器使用這些方法罷了。

            -n
            該選項主要用于調試導致服務器進程異常崩潰的問題。對付這種情況的一般策略是通知所有其它服務器進程終止并重新初始化共享內存和信號燈。這是因為一個出錯的服務器進程可能在終止之前就已經對共享的東西造成了破壞。該選項指定 postgres 不重新初始化共享數據結構。一個有經驗的系統程序員這時就可以使用調試器檢查共享內存和信號燈狀態。

            -O
            允許修改系統表的結構。這個參數用于 initdb

            -P
            讀取系統表時忽略系統索引(但在更改數據時仍然更新索引)。這對于從索引已經損壞的系統表中回復是很有幫助的。

            -t pa[rser] | pl[anner] | e[xecutor]
            打印與每個主要系統模塊相關的查詢記時統計。它不能和 -s 選項一起使用。

            -T
            該選項主要用于調試導致服務器進程異常崩潰的問題。對付這種情況的一般策略是通知所有其它服務器進程終止并重新初始化共享內存和信號燈。這是因為一個出錯的服務器進程可能在終止之前就已經對共享的東西造成了破壞。該選項指定 postgres 通過發送 SIGSTOP 信號停止其他所有服務器進程,但是并不讓它們退出。這樣就允許系統程序員手動從所有服務器進程搜集內核轉儲。

            -v protocol
            聲明這次會話使用的前/后服務器協議的版本數。該選項僅在內部使用。

            -W seconds
            一旦看見這個選項,進程就睡眠標出的秒數。這樣就給開發者一些時間把調試器附著在該服務器進程上。

            -y database
            表明這是一個由父 postgres 進程啟動的子進程,并使用指定的數據庫。該選項僅供內部使用。

            單用戶模式的選項
            下面的選項僅在單用戶模式下可用。

            --single
            選中單用戶模式。這個必須是命令行中的第一個選項。

            database
            要訪問的數據庫名字。如果忽略掉則缺省為用戶名。

            -E
            回顯所有命令

            -j
            禁止使用新行作為語句分隔符

            -r filename
            將所有服務器輸出日志保存到 filename 中。在多用戶模式下該選項將被忽略,所有進程都將使用 stderr

            環境變量
            PGCLIENTENCODING
            客戶端使用的缺省字符編碼。客戶端可以獨立地覆蓋它。這個值也可以在配置文件里設置。

            PGDATA
            缺省數據目錄位置

            PGDATESTYLE
            運行時參數 DateStyle 的缺省值。現在反對使用該環境變量。

            PGPORT
            缺省端口(最好在配置文件中設置)

            TZ
            服務器的時區

            診斷
            一個提到了 semget 或 shmget 的錯誤信息可能意味著你需要重新配置你的內核,提供足夠的共享內存和信號燈。更多討論,參閱節16.4。你也可以通過降低 shared_buffers 值以減少 PostgreSQL 的共享內存的消耗,或者降低 max_connections 值減少 PostgreSQL 的信號燈的消耗。

            如果碰到一個說另外一個服務器正在運行的錯誤信息,可以根據不同的系統使用命令

            $ ps ax | grep postgres或

            $ ps -ef | grep postgres如果確信沒有沖突的服務器正在運行,那么你可以刪除消息里提到的鎖文件然后再次運行。

            抱怨無法綁定端口的錯誤信息可能表明該端口已經被其它非 PostgreSQL 進程使用。如果終止 postgres 后又馬上用同一個端口運行它,也可能得到這個錯誤信息;這時,你必須多等幾秒,等操作系統關閉了該端口后再試。最后,如果你使用了一個操作系統認為是保留的端口,也可能導致這個錯誤信息。例如,我的 Unix 版本認為低于 1024 的端口號是"可信任的",因而只有 Unix 超級用戶可以使用它們。

            注意
            如果有可能,不要使用 SIGKILL 殺死主 postgres 服務器進程。這樣會阻止 postgres 在退出前釋放它持有的系統資源(例如共享內存和信號燈)。這樣可能會影響到將來啟動新的 postgres 進程。

            可以使用 SIGTERM, SIGINT, SIGQUIT 信號正常結束 postgres 服務器進程。第一個信號將等待所有的客戶端退出后才退出。第二個將強制斷開所有客戶端,而第三個將不停止立刻退出,導致在重啟時的恢復運行。SIGHUP 會重新加載服務器配置文件。也可以向一個單獨的服務器進程發送 SIGHUP 信號,但是這樣做沒什么意義。

            pg_ctl 工具可以用于安全而有效地啟停 postgres ,推薦使用。

            要推出一個正在運行的查詢,可以向正在執行該查詢的進程發送 SIGINT 信號。

            主 postgres 服務器進程向子進程發送 SIGTERM 信號讓它們正常退出;發送 SIGQUIT 信號立即退出且不做清理工作,用戶應當盡量避免使用該信號。同時,發送 SIGKILL 信號也是不明智的:主 postgres 進程將把這個信號當作崩潰信號,然后會強制其他兄弟進程作為標準的崩潰回復過程退出。

            臭蟲
            -- 選項在 FreeBSD 或 OpenBSD 上無法運行,應該使用 -c 。這在受影響的系統里是個臭蟲;如果這個毛病沒有修補好,將來的 PostgreSQL 版本將提供一個繞開的辦法。

            用法
            啟動一個單用戶模式的服務器:

            postgres --single -D /usr/local/pgsql/data other-options my_database用 -D 給服務器提供正確的數據庫目錄的路徑,或者確保環境變量 PGDATA 已經正確設置。同時還要聲名你想用的特定數據庫名字。

            通常,獨立運行的服務器把換行符當做命令輸入完成字符;它還不懂分號的作用,因為那些東西是在 psql 里的。要想把一行分成多行寫,你必需在除最后一個換行符以外的每個換行符前面敲一個反斜杠。

            但是如果使用了 -j 命令行選項,新行將不被當作命令結束符。此時服務器將從標準輸入一直讀取到 EOF 標志為止,然后把把所有讀到的內容當作一個完整的命令字符串看待,并且反斜杠與換行符也被當作普通字符來看待。

            輸入 EOF(Control+D)即可退出會話。如果你已經使用了 -j 則必須連續使用兩個 EOF 才行。

            請注意單用戶模式運行的服務器不會提供復雜的行編輯功能(比如,沒有命令行歷史)。

            例子
            用缺省值在后臺啟動 postgres :

            $ nohup postgres >logfile 2>&1 </dev/null &在指定的端口啟動 postgres :

            $ postgres -p 1234這條命令將在端口 1234 啟動 postgres 。你應該這樣使用 psql 與之連接:

            $ psql -p 1234或者設置環境變量 PGPORT :

            $ export PGPORT=1234$ psql命名的運行時參數可以用下列的風格之一設置:

            $ postgres -c work_mem=1234$ postgres --work-mem=1234兩種形式都覆蓋那些現有的在 postgresql.conf 里面的 work_mem 設置。請注意在參數名里的下劃線在命令行上可以寫成下劃線,也可以寫成連字符。除了用于短期的實驗以外,更好的習慣是編輯 postgresql.conf 里面的設置,而不是倚賴命令行開關設置參數。

            又見
            initdb, pg_ctl

            postmaster
            Name
            postmaster -- PostgreSQL 數據庫服務器
            Synopsis
            postmaster [option...]

            Description
            postmaster 是 postgres 的別名,反對使用。

            又見
            postgres

            posted @ 2013-04-22 14:06 多彩人生 閱讀(1190) | 評論 (0)編輯 收藏

            AOP編程

            http://www.cnblogs.com/beliefbetrayal/archive/2012/02/03/2337522.html

            posted @ 2013-04-02 18:13 多彩人生 閱讀(174) | 評論 (0)編輯 收藏

            僅列出標題
            共25頁: First 7 8 9 10 11 12 13 14 15 Last 

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            色8久久人人97超碰香蕉987| 亚洲国产日韩欧美综合久久| 久久精品国产久精国产| 久久亚洲AV永久无码精品| 香港aa三级久久三级| 97久久超碰国产精品旧版| 少妇人妻88久久中文字幕| 亚洲狠狠婷婷综合久久蜜芽| 99久久精品国产毛片| 性欧美大战久久久久久久久| 国产激情久久久久影院老熟女| 日本久久久久久中文字幕| 久久香蕉一级毛片| 色悠久久久久久久综合网| 欧美激情一区二区久久久| 国产免费久久精品99re丫y| 狠狠色丁香婷综合久久| 蜜臀久久99精品久久久久久小说| 久久人人爽人人澡人人高潮AV| 精品国产VA久久久久久久冰 | 久久亚洲AV成人无码国产| 久久久久香蕉视频| 97精品伊人久久大香线蕉| 久久se这里只有精品| 久久久久久久久66精品片| 青草国产精品久久久久久| 亚洲国产日韩欧美综合久久| 久久精品国产精品亚洲人人 | 久久综合狠狠综合久久激情 | 无码久久精品国产亚洲Av影片| 国产99久久久国产精品小说| 久久一区二区免费播放| 精品久久久久久国产牛牛app| 伊人久久精品线影院| 久久精品无码一区二区三区| 国产精品久久久久jk制服| 久久99精品国产自在现线小黄鸭| 久久无码人妻一区二区三区 | 国产激情久久久久影院小草 | 久久国产精品99久久久久久老狼| 久久人妻少妇嫩草AV无码专区|