青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

T9的空間

You will never walk alone!

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  69 隨筆 :: 0 文章 :: 28 評論 :: 0 Trackbacks

置頂隨筆 #

     摘要: 這是在一個百度貼吧里轉(zhuǎn)載的OJ及有用的網(wǎng)址收集!  閱讀全文
posted @ 2008-09-09 21:20 Torres 閱讀(3341) | 評論 (32)編輯 收藏

一直想有一個blog,做做筆記,整理整理思路,基于這個思想,這個blog誕生了!以后就靠這個來祭奠生活了。
posted @ 2008-08-11 12:30 Torres 閱讀(187) | 評論 (1)編輯 收藏

2014年7月8日 #

許下一個美好愿望吧,期望能在空余的時間把多年前買的一本書看完。
Pushing yourself when no one else is around.
posted @ 2014-07-08 20:11 Torres 閱讀(286) | 評論 (0)編輯 收藏

2013年12月9日 #

From Unix某論壇,忘記名字了...但這段文字從宏觀上講清楚了Linux Memory的構(gòu)架。
1.
內(nèi)核初始化:

    *
內(nèi)核建立好內(nèi)核頁目錄頁表數(shù)據(jù)庫,假設(shè)物理內(nèi)存大小為len,則建立了[3G--3G+len]::[0--len]這樣的虛地址vaddr和物理地址paddr的線性對應(yīng)關(guān)系;
    *
內(nèi)核建立一個page數(shù)組,page數(shù)組和物理頁面系列完全是線性對應(yīng),page用來管理該物理頁面狀態(tài),每個物理頁面的虛地址保存在page->virtual中;
    *
內(nèi)核建立好一個free_list,將沒有使用的物理頁面對應(yīng)的page放入其中,已經(jīng)使用的就不用放入了;

2.
內(nèi)核模塊申請內(nèi)存vaddr = get_free_pages(mask,order)

    *
內(nèi)存管理模塊從free_list找到一個page,將page->virtual作為返回值,該返回值就是對應(yīng)物理頁面的虛地址;
    *
pagefree_list中脫離;
    *
模塊使用該虛擬地址操作對應(yīng)的物理內(nèi)存;

3.
內(nèi)核模塊使用vaddr,例如執(zhí)行指令mov(eax, vaddr)

    * CPU
獲得vaddr這個虛地址,利用建立好的頁目錄頁表數(shù)據(jù)庫,找到其對應(yīng)的物理內(nèi)存地址;
    *
eax的內(nèi)容寫入vaddr對應(yīng)的物理內(nèi)存地址內(nèi);

4.
內(nèi)核模塊釋放內(nèi)存free_pages(vaddr,order)

    *
依據(jù)vaddr找到對應(yīng)的page
    *
將該page加入到free_list中;

5.
用戶進(jìn)程申請內(nèi)存vaddr = malloc(size)

    *
內(nèi)存管理模塊從用戶進(jìn)程內(nèi)存空間(0--3G)中找到一塊還沒使用的空間vm_area_struct(start--end)
    *
隨后將其插入到task->mm->mmap鏈表中;

6.
用戶進(jìn)程寫入vaddr(0-3G),例如執(zhí)行指令mov(eax, vaddr)

    * CPU
獲得vaddr這個虛地址,該虛地址應(yīng)該已經(jīng)由glibc庫設(shè)置好了,一定在3G一下的某個區(qū)域,根據(jù)CR3寄存器指向的current->pgd查當(dāng)前進(jìn)程的頁目錄頁表數(shù)據(jù)庫,發(fā)現(xiàn)該vaddr對應(yīng)的頁目錄表項為0,故產(chǎn)生異常;
    *
在異常處理中,發(fā)現(xiàn)該vaddr對應(yīng)的vm_area_struct已經(jīng)存在,為vaddr對應(yīng)的頁目錄表項分配一個頁表;
    *
隨后從free_list找到一個page,將該page對應(yīng)的物理頁面物理首地址賦給vaddr對應(yīng)的頁表表項,很明顯,此時的vaddrpaddr不是線性對應(yīng)關(guān)系了;
    *
pagefree_list中脫離;
    *
異常處理返回;
    * CPU
重新執(zhí)行剛剛發(fā)生異常的指令mov(eax, vaddr)
    * CPU
獲得vaddr這個虛地址,根據(jù)CR3寄存器指向的current->pgd,利用建立好的頁目錄頁表數(shù)據(jù)庫,找到其對應(yīng)的物理內(nèi)存地址;
    *
eax的內(nèi)容寫入vaddr對應(yīng)的物理內(nèi)存地址內(nèi);  

7.
用戶進(jìn)程釋放內(nèi)存vaddrfree(vaddr)

    *
找到該vaddr所在的vm_area_struct
    *
找到vm_area_struct:start--end對應(yīng)的所有頁目錄頁表項,清空對應(yīng)的所有頁表項;
    *
釋放這些頁表項指向物理頁面所對應(yīng)的page,并將這些page加入到free_list隊列中;
    *
有必要還會清空一些頁目錄表項,并釋放這些頁目錄表項指向的頁表;
    *
task->mm->mmap鏈中刪除該vm_area_struct并釋放掉;

綜合說明:

    *
可用物理內(nèi)存就是free_list中各page對應(yīng)的物理內(nèi)存;
    *
頁目錄頁表數(shù)據(jù)庫的主要目的是為CPU訪問物理內(nèi)存時轉(zhuǎn)換vaddr-->paddr使用,分配以及釋放內(nèi)存時不會用到,但是需要內(nèi)核內(nèi)存管理系統(tǒng)在合適時機(jī)為CPU建立好該庫;
    *
對于用戶進(jìn)程在6中獲得的物理頁面,有兩個頁表項對應(yīng),一個就是內(nèi)核頁目錄頁表數(shù)據(jù)庫的某個pte[i ],一個就是當(dāng)前進(jìn)程內(nèi)核頁目錄頁表數(shù)據(jù)庫的某個 pte[j],但是只有一個page和其對應(yīng)。如果此時調(diào)度到其他進(jìn)程,其他進(jìn)程申請并訪問某個內(nèi)存,則不會涉及到該物理頁面,因為其分配時首先要從 free_list中找一個page,而該物理頁面對應(yīng)的page已經(jīng)從free_list中脫離出來了,因此不存在該物理頁面被其他進(jìn)程改寫操作的情況。內(nèi)核中通過get_free_pages等方式獲取內(nèi)存時,也不會涉及到該物理頁面,原理同前所述。
posted @ 2013-12-09 17:42 Torres 閱讀(482) | 評論 (0)編輯 收藏

from: http://www.cnblogs.com/whjiang/articles/1387364.html

1. 盡可能不要創(chuàng)建global reference和global weak reference. 創(chuàng)建這兩類引用的JNI接口NewGlobalReference和NewGlobalWeakReference內(nèi)部實現(xiàn)

有一個鎖。這個鎖使得在多處理器上的可擴(kuò)展性非常差,因為各個線程都在等待這個鎖。所以盡量不要在native保存java 對象的引用,情愿在每次
JNI call時都帶點(diǎn)參數(shù)。當(dāng)然,在native保持java對象的local reference是非常危險的,絕對不能那樣干。

2. 盡量不要使用GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical來pin住Java內(nèi)存。JVM本身沒有提供任何只pin住一塊Java內(nèi)存而不影
響GC的操作,所以這個操作是會阻止GC進(jìn)行的。作為補(bǔ)償,ReleasePrimitiveArrayCritical會產(chǎn)生一次隱式的GC調(diào)用。這樣就可能出現(xiàn)在需要GC的時
候無法GC,而在不需要GC時進(jìn)行無意義GC的情況。另外,這兩個操作的實現(xiàn)中在某些情況下也可能觸發(fā)鎖。解決方法:如果是小塊內(nèi)存的話,情愿使
用Get<Type>ArrayRegion和Set<Type>ArrayRegion來在native和Java之間復(fù)制內(nèi)存。

3. 在Java appliation中盡量不要創(chuàng)建phantom reference或者soft reference。這些reference會極大的影響GC。
我們先來談?wù)凧VM的GC。GC分為minor GC和full GC。Java內(nèi)存分為young和old兩代。在young memory中,每個線程都有自己的內(nèi)存分配塊(不和其它
線程共享),而old memory是由所有線程共享的。minor GC只對young memory作GC,而full GC對所有內(nèi)存都做GC。minor GC是可以多線程并行進(jìn)行的
,而full GC默認(rèn)只能單線程執(zhí)行。所以,一次full GC需要的時間可以是minor GC是10倍以上(可以用-verbose:gc觀察)。所以在一般應(yīng)用中,
minor GC的次數(shù)應(yīng)該是full GC的10倍左右是比較理想的。minor GC會將無法收集的對象移動到old memory中去。

minor GC不會對phantom reference和soft reference進(jìn)行收集,只有full GC才會。這樣的問題就是大量的這類對象積聚起來,產(chǎn)生許多的內(nèi)存復(fù)制。

這樣每次minor GC可能就基本上沒有釋放多少內(nèi)存,使得full GC就會被頻繁觸發(fā)。可能出現(xiàn)minor GC和full GC次數(shù)1:1的情況,甚至全是full GC。

這樣,無論是性能還是可擴(kuò)展性都是非常差的。

weak reference的影響好像小一些,但也應(yīng)該盡量避免。

 

在JNI開發(fā)中,使用這3種reference的主要目的是保證native資源的釋放。因為java對象的finalize方法是不保證被調(diào)用的,所以必須用這些

reference來幫助實現(xiàn)native資源釋放。為了避免上述的問題,一種可行的方法是將native資源serialize成一塊內(nèi)存,然后放到j(luò)ava對象中保存,從
而避免使用這些reference。

4. NIO是不錯的Java和native之間share memory的方法。但要注意它的性能。首先一定要設(shè)置對big endian還是little endian,防止JVM做額外的
endian轉(zhuǎn)換動作。其次是在啟動JVM時一定要加上-server選項,否則nio性能會非常差。在-server mode下,nio性能大概比java數(shù)組慢30%~50%.在-
client mode下,性能差1倍以上。

5. 盡量不要在JNI去new Java String對象。這個比在java層new慢很多。

6. 對java大對象(比方說數(shù)組),一定要仔細(xì)的tune他的大小。一般來說,小對象對GC比較友好。因為對象分配時先看每個線程自己的young memory
,如果找的到足夠大的內(nèi)存的話,就分配。否則在old memory中分配。因為old memory是shared,所以可能有鎖開銷。而且old memory中的對象只有
full GC才能釋放它。所以對象比較小是比較好的。JVM的內(nèi)存分配算法是為小對象優(yōu)化過的,大量小對象的分配是很高效的,所以不用怕把大對象拆小。
在某些情況下,如果知道對象會活的很久的話,就讓它大一點(diǎn),增加它直接分配在old memory中的概率。這樣可以節(jié)約young GC拷貝這個對象到old 

memory中的開銷。

posted @ 2013-12-09 17:40 Torres 閱讀(617) | 評論 (0)編輯 收藏

2013年10月21日 #

第二章
編譯和鏈接
這章比較籠統(tǒng),都是概念,熟悉基本流程的人,建議不看。
 
記錄一些基本流程
 
拿GCC來說
用GCC編譯鏈接生成可執(zhí)行文件的過程分為下面4個步驟
Prepressing,Compilation,Assembly,Linking
 
Prepressing 預(yù)處理
從.c -> .i (gcc -E)
主要是處理,前綴為‘#’的語句
 
define的直接替換
對define這種,從我觀察應(yīng)該是這樣
對源文件類似.c直接掃描 看到define的符號直接加到表中
然后在替換的時候會做遞歸檢查,直到符號是最終定義。
 
所以這個與define的順序沒有太大關(guān)系了,只要不循環(huán)嵌套
 
類似這種
#define M (N + 1)
#define N 2
 
這種在用到M的時候,會先替換成 (N + 1)但是發(fā)現(xiàn)替換的表達(dá)式中還有未決symbol,那么
就再進(jìn)行替換 (2 + 1)
 
表中并不會直接寫成 M (2 + 1),至少我看到的GCC行為是這樣。
 
include的也是直接導(dǎo)入
 
另外預(yù)編譯選項 #ifdef 之類的會處理掉,刪掉所有注釋
 
#pragma是要被保留給編譯器的,這是編譯器選項,例如 pragma pack是用來指定字節(jié)對齊標(biāo)準(zhǔn)的
 
Compilation 編譯
從 .i -> .s (gcc -S)
現(xiàn)在的GCC版本都把預(yù)編譯和編譯做到了一個可執(zhí)行程序中 -> ccl
 
編譯的主要過程
掃描,語法分析,語義分析,源代碼優(yōu)化,代碼生成,目標(biāo)代碼優(yōu)化
Source code --Scanner--> Tokens --Parser--> Syntax Tree
--Semantic Analyzer--> Commented Syntax Tree --Source code Optimizer--> Intermediate Representation
--Code Generator--> Target Code --Code Optimizer-->Final Target Code
 
Assembly 匯編
從 .s -> .o (gcc -c) -->匯編器as
 
Linking 鏈接
ld做的事情
link的時候由于每個源文件都是單獨(dú)編譯,那么必須處理一些外來的symbol
包括函數(shù)和全局變量
posted @ 2013-10-21 17:01 Torres 閱讀(291) | 評論 (0)編輯 收藏

2013年10月18日 #

第一章
印象:
硬件PCI/ISA的架構(gòu)
North Bridge相當(dāng)于人的心臟,連接所有高速設(shè)備,CPU ->大腦
南橋芯片則負(fù)責(zé)低速設(shè)備連接
  
SMP
 
中間層 是解決很多問題的大方向
Any problem in computer science can be resolved by another layer of indirection
 
CPU密集型 IO密集型
這兩種類型的Process,理論上優(yōu)先級高的,也就是說最應(yīng)該先得到CPU的是IO密集型
通俗的理解應(yīng)該是IO密集型做完事情花的CPU時間最少,然后就會等待IO設(shè)備的反應(yīng),這樣可以讓設(shè)備性能最大化
 
Memory
分段分頁 MMU
 

線程安全和線程模型
 

其中線程安全有兩件事情要注意
Semaphore
Mutex
上面這兩個可以做成全局的,并不一定是By Process的,例如POSIX pthread在
對Mutex做attr設(shè)定的時候就可以指定為 shared process
也就是說一個Process可以加鎖,另外一個可以釋放他。
另外這種Mutex必須處在共享內(nèi)存中,否則沒辦法訪問。有親緣關(guān)系的Process可以通過mmap一個匿名映射做到
anyway有很多方式了。
 
Critical Section
這個是Inter Process的東西。
 
關(guān)于線程互斥的lock的問題
RW lock就是對普通lock記錄兩個狀態(tài)來供read or write操作選擇
 
屬于線程本身的東西 TLS/Stack/Register
 
有時候編譯器會為了做優(yōu)化
內(nèi)存和寄存器的數(shù)據(jù)會出現(xiàn)不sync的狀態(tài)。
即使你用lock來做保護(hù),也不一定能OK。然后volatile就出現(xiàn)了。 
 
volatile最主要的作用就是thread內(nèi)保證編譯器不要做優(yōu)化,防止這種不sync帶來的問題。
一般是這樣例如x變量,thread_1讀到x變量放到了寄存器中,因為可能馬上會再訪問它,那么對x進(jìn)行操作后就不會寫回內(nèi)存
這樣即使你加了lock,這個時候lock也被釋放掉了(操作完成),但是結(jié)果未能Sync,那么thread 2來訪問x的時候,在內(nèi)存
中拿到的值就變成dirty狀態(tài)了。
 
另外一種過度優(yōu)化就是CPU做的優(yōu)化,有些上下語義無關(guān)的指令,CPU有可能會調(diào)整運(yùn)行順序。
書中有個經(jīng)典樣例
一段 Singleton pattern的double-check的代碼
volatile T* pInst = NULL;
T* getInstance()
{
if (pInst == NULL)
{
lock();
if (pInst == NULL)
pInst = new T();
unlock();
}
return pInst;
}

 
這里有兩點(diǎn)
第一,double-check 也就是雙if能避免過多的無用的get lock,降低消耗
對臨界區(qū)需要做保護(hù)的資源,可以提前去取狀態(tài),如果符合自己的預(yù)期,而且短時間不會有變化,那么就不用去拿鎖了
不知道為啥我想到了unlikely,但仔細(xì)想一下,功能完全不同。
 
第二點(diǎn)也就是要說的CPU的過度優(yōu)化
這里已經(jīng)是聲明volatile了,所以沒有寄存器和內(nèi)存不sync的問題
但是由于這里new需要先 malloc出空間,然后call T的constructor。
所以有可能會發(fā)生這種情況,malloc出空間后,把地址付給pInst,然后去做初始化;
這樣就有可能另外一個線程取得的object是沒有被完全初始化好的,是否會出問題depend on T的具體實現(xiàn)了。
許多CPU提供了barrier指令用來解決上面提到的問題。
 
線程模型
這個東西,我看了下,開始沒看明白,這邊書這個東西沒講清楚,后來去網(wǎng)上找了些資料。用戶線程和內(nèi)核線程的對應(yīng)關(guān)系取決于調(diào)度單位。
也就是說內(nèi)核把什么東西當(dāng)做一個調(diào)度單位
 
拿Linux來說吧,Process是線程集和資源集
 
調(diào)度的時候,那些共享資源的Task(thread)之間的調(diào)度肯定比那些跨Process不共享資源的thread做context switch消耗的資源
多得多。
 
基于調(diào)度消耗之類的考量
模型分為下面幾種
 
一對一,也就是說 user space create出來的線程就是和kernel的調(diào)度單位相同,稱一一對應(yīng)
 
一對多,應(yīng)該是這樣一種情況,kernel看到的是Process,userspace自己實現(xiàn)出來自己的thread,這個thread,kernel是不知道的
調(diào)度的時候kernel負(fù)責(zé)分批CPU給他能看到的Process,上層userspace自己來調(diào)度分配這個Process獲得的CPU time給這個process中的
各個線程。
這樣的分配就可以保證在一定的時間內(nèi)只需要做一些register和stack的切換,不會有memory等等的switch。
壞處是上面的thread只要一個被suspend,那么這個Process里面的其他thread也就被suspend住了,一般上層調(diào)度程序
不會假定其他的thread能run,所以一般會是kernel把CPU time給其他process
 
多對多,就是一種混合的情況了,我想到了Android,但是Android是一對一模型,dalvik會保證Java thread對應(yīng)下面一個
native thread,想說的是,這種虛擬機(jī)架構(gòu)可以做成多對多的樣子,一個native thread run一個JVM,JVM開出來很多Java Thread,
JVM負(fù)責(zé)調(diào)度這些Java Thread,Native負(fù)責(zé)調(diào)度JVM所在的Thread。
不知道我有沒有講錯。

posted @ 2013-10-18 19:42 Torres 閱讀(295) | 評論 (0)編輯 收藏

2013年10月14日 #

     之前就翻過一次,這次再看看,期望這次能讀到我想知道的東西...
     這個書的名字我自己覺得有點(diǎn)屌絲風(fēng)格了,Orz,期望編者勿怪
posted @ 2013-10-14 17:07 Torres 閱讀(256) | 評論 (0)編輯 收藏

2013年6月7日 #

偽終端.

這個是Muxd一直用的東西
相當(dāng)于一個雙向PIPE
Process A open ptm得到fdm,然后fork出process B,process B open pts得到fds,然后將0,1,2都dup到fds上
那么fds就變成了process B的控制終端
后面再process B中做標(biāo)準(zhǔn)IO操作的時候就會像PIPE直接影響到fdm
終端行規(guī)程在pts之上

沒什么特別要記錄的,在網(wǎng)上search了下,貼個鏈接,里面會介紹一些基本概念.
http://www.cnblogs.com/Anker/archive/2012/12/25/2832568.html

posted @ 2013-06-07 18:52 Torres 閱讀(271) | 評論 (0)編輯 收藏

終端IO
每個終端都有輸入輸出隊列
隊列都有長度,如果輸入超過輸入隊列MAX_INPUT長度,大多數(shù)unix系統(tǒng)會回顯響鈴來處理。
但是對于輸出隊列來講,雖然輸出隊列也有長度,但是一旦寫不進(jìn)去的時候,寫進(jìn)程會suspend掉
直至有空閑空間

終端行規(guī)程 terminal line discipline
會幫忙做規(guī)范處理

終端設(shè)備屬性 ->termios

struct termios {
 tcflag_t c_iflag;
 tcflag_t c_oflag;
 tcflag_t c_cflag;
 tcflag_t c_lflag;
 cc_t c_line;
 cc_t c_cc[NCCS];
};

local flag影響驅(qū)動程序和用戶之間的接口
Android上tcflag_t->
typedef unsigned int tcflag_t;

cc_t
typedef unsigned char cc_t;

control flag中很多選項標(biāo)志都是用幾位標(biāo)識然后用或來做選擇

isatty的實現(xiàn),借助tcgetattr的出錯機(jī)制,成功返回0;否則返回-1,帶上ENOTTY

int
isatty (int  fd)
{
  struct termios term;

  return tcgetattr (fd, &term) == 0;
}

Anyway,終端IO很復(fù)雜...

posted @ 2013-06-07 14:40 Torres 閱讀(310) | 評論 (0)編輯 收藏

2013年6月6日 #

IPC

首先講到的是PIPE,這個并不陌生,相互通信的Process必須具有關(guān)系,一般是同父親的
然后講到了協(xié)同進(jìn)程
基本是說有一個進(jìn)程專門用來接收輸入,然后處理,然后返回結(jié)果
這個就可以用PIPE來實現(xiàn)

創(chuàng)建兩個PIPE,一個用于輸入給協(xié)同進(jìn)程,另外一個用于接收協(xié)同進(jìn)程的輸出
fork之后在子進(jìn)程中將標(biāo)準(zhǔn)輸入輸出都dup到管道上

而協(xié)同進(jìn)程的寫法可以比較common,只用關(guān)心標(biāo)準(zhǔn)輸入輸出。
PIPE在寫的時候如果有多個寫進(jìn)程,那么寫的數(shù)據(jù)小于 PIPE_BUF 則不會亂序,否則自己應(yīng)該就需要做同步了。

然后就是FIFO,這個就是用mkfifo創(chuàng)建一個file,大家都去用。
PIPE和FIFO都是半雙工的

XSI IPC ->即之前System V IPC
消息隊列 信號量 共享存儲器

在無關(guān)進(jìn)程之間共享存儲段,一個是使用上面V系統(tǒng)shm;另外一個是使用mmap將同一文件map到他們自己的進(jìn)程空間。

另外就是網(wǎng)絡(luò)IPC了
算是復(fù)習(xí)下吧,之前這塊兒看的比較多
int socket(int domain, int type, int protocol)
domain標(biāo)識address family -> AF_INET, AF_INET6, AF_UNIX(AF_LOCAL), AF_UNSPEC
type標(biāo)識socket類型 -> SOCK_DGRAM(UDP), SOCK_RAW(IP), SOCK_SEQPACKET, SOCK_STREAM(TCP)

一般protocol都設(shè)置為0,一般address family和type就能確認(rèn)要使用的protocol

SOCK_SEQPACKET和SOCK)STREAM很像,前一個提供面向數(shù)據(jù)報文的服務(wù),而后面這種則是面對流。
SOCK_SEQPACKET使用場景SCTP,貼一個SCTP的簡要介紹。
http://www.cnblogs.com/qlee/archive/2011/07/13/2105717.html

涉及網(wǎng)絡(luò)就必須要清楚字節(jié)序的問題,字節(jié)序與字符編碼是兩件不同的事情,都要想清楚的,但是要提一下UTF-8這是一種專門設(shè)計用來做網(wǎng)絡(luò)傳輸?shù)淖址幋a
無需關(guān)心字節(jié)序的問題,所以傳輸?shù)纳蠈訑?shù)據(jù)可以用UTF-8,就不用擔(dān)心local host和remote host的主機(jī)字節(jié)序不一樣而導(dǎo)致亂序了。

但是很多協(xié)議頭必須做符合TCP/IP協(xié)議的字節(jié)序規(guī)范,TCP/IP是big endian
關(guān)于Big endian和Litter endian我比較容易忘記具體的樣子,但是他的出發(fā)點(diǎn)是低地址,低地址裝的是最高有效字節(jié)那么就是big endian,否則就是litter endian。

關(guān)于socket有幾個可能比較模糊的地方
connect時,也就是client端,如果fd沒有綁定到某個地址,那么kernel會幫忙將其綁定到默認(rèn)地址; 所以bind這件事情是Client和Server都需要做的事情,調(diào)用listen之前也一樣
然后accept的時候,如果你關(guān)心對方的地址,那么提供addr(足夠)和len,返回的時候就能知道。
另外UDP(SOCK_DGRAM)也可以Call connect,之后就可以直接call send/write,而不必每次都call sendto指定對端地址。

sendto中flag一般給0,如果是緊急數(shù)據(jù)給MSG_OOB

文件描述符的傳輸,目的是想讓不同的process在不同的文件描述符中共享文件表。
所以做法上系統(tǒng)會這樣,傳輸文件表指針然后放到接收端的第一個可用的文件描述符上。
這個我在linux上沒找到實現(xiàn),因為這個功能還是有蠻多替代方案的。

posted @ 2013-06-06 17:22 Torres 閱讀(285) | 評論 (0)編輯 收藏

2013年6月5日 #

13章在講Daemon Process,沒什么特別好寫的。
14 ->高級IO

低速系統(tǒng)調(diào)用,也就是有信號發(fā)生會返回 errno 為 EINTR的

磁盤文件IO雖然有延時,但是這個不能算是低速系統(tǒng)調(diào)用

APUE介紹的低速系統(tǒng)調(diào)用
PIPE,終端設(shè)備,網(wǎng)絡(luò)設(shè)備 讀寫
讀無數(shù)據(jù)/寫無空間(例如TCP卡Congestion window)

打開某些特殊文件
加記錄鎖的文件讀寫
ioctl,IPC


文件鎖又叫做 byte-range locking,針對特定的文件區(qū)域,適合數(shù)據(jù)庫文件
Posix標(biāo)準(zhǔn)
int fcntl(int fd, int cmd, .../* struct flock* flockptr */)
cmd -> F_GETLK,F_SETLK,F_SETLKW
F_SETLKW是F_SETLK的Blocking版本 W means wait

重要數(shù)據(jù)結(jié)構(gòu)是struct flock ->
struct flock {
 short l_type;
 short l_whence;
 off_t l_start;
 off_t l_len;
 pid_t l_pid;
 __ARCH_FLOCK_PAD
};

鎖定整個file的方式: l_whence = SEEK_SET, l_start = 0, l_len = 0

l_type的兩類lock
F_RDLCK,F(xiàn)_WRLCK這兩種鎖的特性很像rw lock

不過與讀寫鎖不一樣的是或者這樣講
Posix.1沒有規(guī)定下面這種情況: process A在某文件區(qū)間上設(shè)置了一把讀鎖;process B嘗試在這個文件區(qū)間加上寫鎖的時候suspend;process C再嘗試獲取讀鎖,如果允許

process C拿到讀鎖,那么process B將會可能永遠(yuǎn)拿不到寫鎖,活活餓死

pthread里面的rw lock的實現(xiàn)會在這種情況下suspend掉process C的讀鎖請求;但是目前文件區(qū)域鎖的實現(xiàn)我不太確定

這里看文件區(qū)域鎖還是比較容易帶來deadlock的
例如process A鎖住F1的某個區(qū)域,然后去鎖F2的一個區(qū)域,這時候F2的這個區(qū)域被process B鎖住,那么process A就會suspend,如果這個時候process B過來要鎖F1的這個區(qū)域
就會發(fā)生deadlock


關(guān)于文件區(qū)域鎖的繼承和釋放
1.fork后,文件區(qū)域鎖并不繼承,繼承了就完了,不同的process就有可能同時干同一件事情,把數(shù)據(jù)搞壞
2.close(fd)后 fd對應(yīng)的文件鎖就被釋放了,文件鎖掛在inode上,close的時候kernel會去掃描對應(yīng)的inode上與這個PID相關(guān)的lock,釋放掉,而并不去關(guān)心是哪個文件描述符或

者是哪個文件表,這很重要,因為lockf中并不記錄fd,他們只是弱關(guān)聯(lián)關(guān)系,這個很重要。
3.exec后,文件鎖會繼承原來執(zhí)行程序的鎖(fork之后拿到的lock),如果fd帶有close-on-exec那么根據(jù)第二條,這個fd對應(yīng)的file上的鎖都會被釋放。


后面講了STREAMS,感覺linux上用到的不多,需要在編譯kernel時動態(tài)加載

IO多路轉(zhuǎn)接,主要是為了實現(xiàn)polling既所謂的輪詢
主要函數(shù)有select,pselect,poll,epoll
select也會算是低速系統(tǒng)調(diào)用,那么就有可能被信號打斷
pselect有參數(shù)可以設(shè)定信號屏蔽集,也提供更高精度的timer

poll的方式與select有不太一樣的地方,但是功能相同,epoll更適合大數(shù)據(jù)量。

readv和writev
記住下面兩條就夠了
一個稱為scatter read(散步讀);另外一個稱為gather write(聚集寫)
這兩個函數(shù)會面對一個buffer鏈表。


readn和writen
這個比較像現(xiàn)在Android里面socket的read和write方式,保證能read/write n byte數(shù)據(jù),在內(nèi)部做循環(huán)
我比較好奇這兩個是否會處理signal,想來應(yīng)該是會處理的,遇到EINTR幫忙重啟就好了

我沒有找到Bionic庫的實現(xiàn)


存儲映射IO
這個很重要,mmap用的很多,映射到process空間的位置在 stack以下,heap以上的部分,map完后返回低地址。

#include<sys/mman.h>
void* mmap(void* addr, size_t len, int prot, int flag, int filedes, off_t off)

prot -> PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE
prot指定的對映射存儲區(qū)的保護(hù)不能超過文件的open權(quán)限

在 flag為 MAP_FIXED的時候OS會保證分配的memory起始地址為addr,否則只是給OS一個建議。
一般建議addr給0,讓OS來決定。

MAP_SHARED是說對映射區(qū)域的存儲(write)會導(dǎo)致修改該文件。
MAP_PRIVATE則是對映射區(qū)域的操作會常見一個映射文件的副本。


后面有個例子用了lseek
使用lseek增加文件長度的方式,先lseek一個值,如果這個值大于文件本身的長度,那么下一次寫就會加長該文件,并且在文件
中形成一個空洞,未寫過的內(nèi)容全部讀為0。
mmap只能map文件的最大長度,超過的地方?jīng)]辦法同步到文件。

posted @ 2013-06-05 16:59 Torres 閱讀(340) | 評論 (0)編輯 收藏

僅列出標(biāo)題  下一頁
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲男同1069视频| 亚洲一级特黄| 欧美激情a∨在线视频播放| 久久精品最新地址| 亚洲第一免费播放区| 欧美国产一区二区在线观看| 欧美华人在线视频| 亚洲一区二区黄色| 香蕉久久国产| 亚洲欧洲一二三| 99在线精品观看| 国产一区二区激情| 亚洲国产成人一区| 欧美视频你懂的| 久久精品99| 欧美国产国产综合| 欧美在线视频一区二区| 久久免费视频这里只有精品| 亚洲精品欧美日韩| 午夜精品一区二区三区在线 | 在线亚洲一区二区| 狠狠色综合播放一区二区| 最新国产成人av网站网址麻豆| 国产精品国产| 欧美激情视频一区二区三区免费| 欧美日韩在线不卡一区| 麻豆精品传媒视频| 欧美亚男人的天堂| 亚洲高清av| 黄色在线一区| 亚洲一区二区视频在线| 亚洲每日更新| 久久精品免费播放| 性伦欧美刺激片在线观看| 在线播放国产一区中文字幕剧情欧美| 久久综合伊人77777| 宅男精品视频| 男女激情久久| 久久精品人人做人人爽| 欧美人成免费网站| 欧美高清在线播放| 国产一区在线观看视频| 亚洲视频成人| 一区二区av在线| 美女视频网站黄色亚洲| 久久蜜臀精品av| 国产欧美日本一区视频| 一区二区三区国产盗摄| 亚洲最新在线视频| 欧美黄色aaaa| 亚洲国产影院| 亚洲欧洲日产国产网站| 久久亚洲精品视频| 一区二区三区在线免费播放| 韩国av一区二区三区四区| 亚洲精品欧美日韩| 在线日韩欧美| 欧美在线视频二区| 久久精品最新地址| 韩国一区电影| 久久av一区二区三区亚洲| 久久久91精品国产| 国内精品久久久久久久影视蜜臀| 亚洲女人小视频在线观看| 羞羞色国产精品| 国产欧美日韩麻豆91| 性色av香蕉一区二区| 久久婷婷影院| 久久在线免费观看| 欧美中文在线免费| 久久久久久网站| 狠狠色综合网| 老司机aⅴ在线精品导航| 欧美国内亚洲| 一区二区日韩精品| 国产精品女人毛片| 欧美一区在线看| 免费日韩av片| 一区二区不卡在线视频 午夜欧美不卡在| 欧美激情一区三区| 亚洲免费网址| 欧美不卡激情三级在线观看| 亚洲精品免费在线| 国产精品入口夜色视频大尺度| 亚洲免费中文| 欧美国产日韩一区二区三区| 一本色道久久88精品综合| 国产精品入口| 麻豆精品精华液| 一本综合精品| 狼人社综合社区| 亚洲香蕉成视频在线观看| 国产日韩三区| 欧美精品成人一区二区在线观看| 一区二区三区高清在线| 久久婷婷国产麻豆91天堂| 一区二区久久久久| 国内外成人在线视频| 欧美人交a欧美精品| 西瓜成人精品人成网站| 91久久精品国产91性色tv| 性欧美1819性猛交| 亚洲每日更新| 在线欧美一区| 国产精品久久久一区二区三区 | 日韩亚洲欧美一区| 国产视频一区欧美| 欧美午夜精彩| 欧美 日韩 国产 一区| 午夜精品在线看| 亚洲美女区一区| 欧美国产日韩一区二区在线观看| 性欧美暴力猛交69hd| 日韩一区二区精品视频| 精品二区视频| 国产亚洲欧美色| 国产精品久久久久aaaa九色| 欧美高清成人| 久久亚洲精品伦理| 久久经典综合| 午夜精品视频在线| 中日韩美女免费视频网址在线观看| 欧美激情精品| 蜜臀久久久99精品久久久久久| 欧美一级视频免费在线观看| 亚洲综合成人婷婷小说| 欧美制服丝袜| 夜夜嗨av色综合久久久综合网| 久久久亚洲影院你懂的| 亚洲制服少妇| 一二三区精品福利视频| 亚洲人成人一区二区三区| 在线精品视频免费观看| 国产在线拍偷自揄拍精品| 国产精品一区二区三区久久久| 欧美视频在线观看 亚洲欧| 欧美激情亚洲精品| 欧美精品18| 欧美精品一区二区视频| 欧美黄色精品| 欧美日韩一区二区三区四区在线观看| 欧美电影免费观看高清完整版| 欧美va天堂在线| 欧美极品色图| 国产精品mv在线观看| 国产精品久久看| 国产亚洲一区二区在线观看| 国产亚洲激情| 亚洲大胆美女视频| 亚洲精品久久久久久一区二区| 亚洲人体1000| 亚洲区免费影片| 宅男噜噜噜66一区二区| 亚洲一区二区三区在线播放| 午夜精品久久久久久久男人的天堂| 亚洲欧美日韩视频一区| 久久国产精彩视频| 欧美成人官网二区| 亚洲美女视频在线观看| 亚洲一区在线看| 久久久久久久波多野高潮日日| 免费黄网站欧美| 欧美午夜在线一二页| 国产香蕉久久精品综合网| 亚洲电影免费在线观看| 一区二区三区欧美在线| 久久精品伊人| 亚洲精美视频| 欧美一级一区| 欧美精品久久久久久久久老牛影院| 国产精品分类| 亚洲电影免费观看高清| 亚洲一区二区影院| 免费成人性网站| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲婷婷综合色高清在线| 久久久久久网站| 国产精品老女人精品视频| 亚洲国产日韩欧美| 香蕉国产精品偷在线观看不卡| 欧美成人午夜激情在线| 亚洲一区免费网站| 欧美激情一区二区三区| 国语精品一区| 午夜精品久久| 亚洲另类视频| 欧美sm视频| 黄色在线一区| 久久狠狠婷婷| 夜夜嗨av色综合久久久综合网| 美女999久久久精品视频| 国产精品手机视频| 中国亚洲黄色| 亚洲人屁股眼子交8| 久久久久高清| 国内精品久久久久久| 欧美一区二区三区视频在线| 亚洲毛片在线看| 欧美激情一区二区在线| 亚洲国产精品黑人久久久|