亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: 內(nèi)核源碼kfifo分析(原創(chuàng)) [打印本頁]

作者: springtty    時(shí)間: 2009-03-23 01:35
標(biāo)題: 內(nèi)核源碼kfifo分析(原創(chuàng))
從2.6.10開始,Linux內(nèi)核提供了一個(gè)通用的環(huán)形緩存(我喜歡稱為環(huán)形隊(duì)列);它的頭文件是<linux/kfifo.h>,kfifo.c是實(shí)現(xiàn)代碼。
在設(shè)備驅(qū)動(dòng)中環(huán)形緩存出現(xiàn)相當(dāng)多. 網(wǎng)絡(luò)適配器, 特別地, 常常使用環(huán)形緩存來與處理器交換數(shù)據(jù)(報(bào)文)[LDD3]。

見下面的圖“LDD3中描述的隊(duì)列”。

我們來看下kfifo的數(shù)據(jù)結(jié)構(gòu):

struct kfifo {
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *buffer;&nbsp;&nbsp;&nbsp;&nbsp;/* the buffer holding the data */
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int size;&nbsp;&nbsp;&nbsp;&nbsp;/* the size of the allocated buffer */
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int in;&nbsp;&nbsp;&nbsp;&nbsp;/* data is added at offset (in % size) */
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int out;&nbsp;&nbsp;&nbsp;&nbsp;/* data is extracted from off. (out % size) */
&nbsp;&nbsp;&nbsp;&nbsp;spinlock_t *lock;&nbsp;&nbsp;&nbsp;&nbsp;/* protects concurrent modifications */
};


如E文注釋所解,buffer指向隊(duì)列空間,對(duì)于隊(duì)列的操作,一般會(huì)涉及到讀寫,如果是多線程的話,就有可能涉及到生產(chǎn)者/消費(fèi)者,也稱讀者/寫者問題;
size表示空間大小,必須為2^k,如果不是2^k大小,kfifo將會(huì)幫助用戶擴(kuò)展到一個(gè)合適的大;
in表示寫者指向的索引,在kfifo體統(tǒng)的put函數(shù)中,被處理為一個(gè)虛擬索引(我暫這么稱呼)。之所以稱之為虛擬索引,是因?yàn)樵撍饕⒉灰欢ㄕ嬲赶蛴行У牡刂房臻g,而是要通過一定運(yùn)算才能得到真實(shí)的索引。下面的put/get代碼分析將會(huì)看到內(nèi)核是kfifo是怎么運(yùn)算的。
out表示讀者指向的索引,out的更新與in一樣,都是使用了虛擬索引的概念,out總是小于等于in。

我們直接來看代碼(保留了原來的注釋,//后面的內(nèi)容為筆者的解釋)

/**
&nbsp;* kfifo_init - allocates a new FIFO using a preallocated buffer
&nbsp;* @buffer: the preallocated buffer to be used.
&nbsp;* @size: the size of the internal buffer, this have to be a power of 2.
&nbsp;* @gfp_mask: get_free_pages mask, passed to kmalloc()
&nbsp;* @lock: the lock to be used to protect the fifo buffer
&nbsp;*
&nbsp;* Do NOT pass the kfifo to kfifo_free() after use! Simply free the
&nbsp;* &struct kfifo with kfree().
&nbsp;*/

struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gfp_t gfp_mask, spinlock_t *lock)
{
&nbsp;&nbsp;&nbsp;&nbsp;struct kfifo *fifo;

&nbsp;&nbsp;&nbsp;&nbsp;/* size must be a power of 2 */
&nbsp;&nbsp;&nbsp;&nbsp;BUG_ON(size & (size - 1)); //大小必須為2的k次方(k>0)的目的在于put/get中從虛擬索引計(jì)算真實(shí)索引,size & (size - 1)是常用判斷技巧


&nbsp;&nbsp;&nbsp;&nbsp;fifo = kmalloc(sizeof(struct kfifo), gfp_mask); //分配kfifo數(shù)據(jù)結(jié)構(gòu)

&nbsp;&nbsp;&nbsp;&nbsp;if (!fifo)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ERR_PTR(-ENOMEM);

&nbsp;&nbsp;&nbsp;&nbsp;fifo->buffer = buffer;
&nbsp;&nbsp;&nbsp;&nbsp;fifo->size = size;
&nbsp;&nbsp;&nbsp;&nbsp;fifo->in = fifo->out = 0; //當(dāng)fifo->in == fifo->out 時(shí),表示空隊(duì)列

&nbsp;&nbsp;&nbsp;&nbsp;fifo->lock = lock;

&nbsp;&nbsp;&nbsp;&nbsp;return fifo;
}


/**
&nbsp;* kfifo_alloc - allocates a new FIFO and its internal buffer
&nbsp;* @size: the size of the internal buffer to be allocated.
&nbsp;* @gfp_mask: get_free_pages mask, passed to kmalloc()
&nbsp;* @lock: the lock to be used to protect the fifo buffer
&nbsp;*
&nbsp;* The size will be rounded-up to a power of 2.
&nbsp;*/

//通過調(diào)用kfifo_alloc分配隊(duì)列空間,該函數(shù)會(huì)調(diào)用kfifo_init初始化kfifo結(jié)構(gòu)體,并調(diào)整size的大小以適應(yīng)運(yùn)算

struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *buffer;
&nbsp;&nbsp;&nbsp;&nbsp;struct kfifo *ret;

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * round up to the next power of 2, since our 'let the indices
&nbsp;&nbsp;&nbsp;&nbsp; * wrap' tachnique works only in this case.
&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;if (size & (size - 1)) { //如果size不是2的k次方,代碼將size調(diào)整最近的2^k次方附近

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUG_ON(size > 0x80000000);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size = roundup_pow_of_two(size);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;buffer = kmalloc(size, gfp_mask);
&nbsp;&nbsp;&nbsp;&nbsp;if (!buffer)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ERR_PTR(-ENOMEM);

&nbsp;&nbsp;&nbsp;&nbsp;ret = kfifo_init(buffer, size, gfp_mask, lock);

&nbsp;&nbsp;&nbsp;&nbsp;if (IS_ERR(ret))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kfree(buffer);

&nbsp;&nbsp;&nbsp;&nbsp;return ret;
}

/**
&nbsp;* __kfifo_put - puts some data into the FIFO, no locking version
&nbsp;* @fifo: the fifo to be used.
&nbsp;* @buffer: the data to be added.
&nbsp;* @len: the length of the data to be added.
&nbsp;*
&nbsp;* This function copies at most @len bytes from the @buffer into
&nbsp;* the FIFO depending on the free space, and returns the number of
&nbsp;* bytes copied.
&nbsp;*
&nbsp;* Note that with only one concurrent reader and one concurrent
&nbsp;* writer, you don't need extra locking to use these functions.
&nbsp;*/

unsigned int __kfifo_put(struct kfifo *fifo,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *buffer, unsigned int len)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int l;

&nbsp;&nbsp;&nbsp;&nbsp;//fifo->size - fifo->in + fifo->out,這段代碼計(jì)算空閑的空間

&nbsp;&nbsp;&nbsp;&nbsp;//in是寫索引,out是讀索引,而且put與get操作都是分別增加in與out的值來重新計(jì)算虛擬索引

&nbsp;&nbsp;&nbsp;&nbsp;//注意,out 始終不會(huì)大于 in,(in - out)是有效數(shù)據(jù)空間大小,size是總空間的大小

&nbsp;&nbsp;&nbsp;&nbsp;//那么空閑的空間大小就是 size - (int - out)

&nbsp;&nbsp;&nbsp;&nbsp;//如果請(qǐng)求的len大于空閑空間,就使len = size - (int - out)

&nbsp;&nbsp;&nbsp;&nbsp;len = min(len, fifo->size - fifo->in + fifo->out);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we sample the fifo->out index -before- we
&nbsp;&nbsp;&nbsp;&nbsp; * start putting bytes into the kfifo.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_mb();

&nbsp;&nbsp;&nbsp;&nbsp;/* first put the data starting from fifo->in to buffer end */
&nbsp;&nbsp;&nbsp;&nbsp;//(fifo->in & (fifo->size - 1))這段代碼計(jì)算真實(shí)的寫索引偏移,筆者假設(shè)為real_in

&nbsp;&nbsp;&nbsp;&nbsp;//這是因?yàn)閕n在每次調(diào)用put之后都會(huì)增加一個(gè)len的長(zhǎng)度

&nbsp;&nbsp;&nbsp;&nbsp;//由于fifo->size必定是2的k次方,而(fifo->size - 1)就是類似0x00FFFFF的值

&nbsp;&nbsp;&nbsp;&nbsp;//(fifo->in & (fifo->size - 1))的操作從數(shù)學(xué)角度將就是對(duì)長(zhǎng)度fifo->size的取模運(yùn)算

&nbsp;&nbsp;&nbsp;&nbsp;//這里能用AND運(yùn)算代替取模運(yùn)算得益于前面申請(qǐng)的空間大小為2^k次方

&nbsp;&nbsp;&nbsp;&nbsp;//l = min(空閑空間大小,從real_in開始到緩沖區(qū)結(jié)尾的空間)

&nbsp;&nbsp;&nbsp;&nbsp;l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));

&nbsp;&nbsp;&nbsp;&nbsp;//先從buffer中拷貝l字節(jié)到緩沖區(qū)剩余空間,l<=len,也<=從real_in開始到緩沖區(qū)結(jié)尾的空間

&nbsp;&nbsp;&nbsp;&nbsp;//所以這個(gè)copy可能沒拷貝完,但是不會(huì)造成緩沖區(qū)越界

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);

&nbsp;&nbsp;&nbsp;&nbsp;/* then put the rest (if any) at the beginning of the buffer */
&nbsp;&nbsp;&nbsp;&nbsp;//當(dāng)len > l時(shí),拷貝buffer中剩余的內(nèi)容,其實(shí)地址當(dāng)然為buffer + l,而剩余的大小為len - l

&nbsp;&nbsp;&nbsp;&nbsp;//當(dāng)len == l時(shí),下面的memcpy啥都不干,絕對(duì)精妙的算法

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(fifo->buffer, buffer + l, len - l);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we add the bytes to the kfifo -before-
&nbsp;&nbsp;&nbsp;&nbsp; * we update the fifo->in index.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_wmb();

&nbsp;&nbsp;&nbsp;&nbsp;//更新in(寫者)的邏輯索引

&nbsp;&nbsp;&nbsp;&nbsp;fifo->in += len;

&nbsp;&nbsp;&nbsp;&nbsp;return len;
}

/**
&nbsp;* __kfifo_get - gets some data from the FIFO, no locking version
&nbsp;* @fifo: the fifo to be used.
&nbsp;* @buffer: where the data must be copied.
&nbsp;* @len: the size of the destination buffer.
&nbsp;*
&nbsp;* This function copies at most @len bytes from the FIFO into the
&nbsp;* @buffer and returns the number of copied bytes.
&nbsp;*
&nbsp;* Note that with only one concurrent reader and one concurrent
&nbsp;* writer, you don't need extra locking to use these functions.
&nbsp;*/

unsigned int __kfifo_get(struct kfifo *fifo,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *buffer, unsigned int len)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int l;
&nbsp;&nbsp;&nbsp;&nbsp;//讀取的大小不能超過有效空間長(zhǎng)度

&nbsp;&nbsp;&nbsp;&nbsp;//經(jīng)過min運(yùn)算后len <= 請(qǐng)求的空間len, len <= size

&nbsp;&nbsp;&nbsp;&nbsp;len = min(len, fifo->in - fifo->out);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we sample the fifo->in index -before- we
&nbsp;&nbsp;&nbsp;&nbsp; * start removing bytes from the kfifo.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_rmb();

&nbsp;&nbsp;&nbsp;&nbsp;/* first get the data from fifo->out until the end of the buffer */
&nbsp;&nbsp;&nbsp;&nbsp;//同理,fifo->out & (fifo->size - 1)等于out(讀者)的虛擬索引計(jì)算出來真實(shí)索引real_out

&nbsp;&nbsp;&nbsp;&nbsp;//fifo->size - real_out就等于該索引到緩沖區(qū)尾部的空間大小

&nbsp;&nbsp;&nbsp;&nbsp;//經(jīng)過min運(yùn)算后,l<=len,l<=real_out至緩沖區(qū)尾部的空間大小

&nbsp;&nbsp;&nbsp;&nbsp;l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));

&nbsp;&nbsp;&nbsp;&nbsp;//從real_out開始拷貝l字節(jié)內(nèi)容到buffer中

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);

&nbsp;&nbsp;&nbsp;&nbsp;/* then get the rest (if any) from the beginning of the buffer */
&nbsp;&nbsp;&nbsp;&nbsp;//如果l<len,那么從fifo->buffer的首部開始繼續(xù)拷貝剩下的內(nèi)容

&nbsp;&nbsp;&nbsp;&nbsp;//如果l == len,memcpy啥都不干

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(buffer + l, fifo->buffer, len - l);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we remove the bytes from the kfifo -before-
&nbsp;&nbsp;&nbsp;&nbsp; * we update the fifo->out index.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_mb();

&nbsp;&nbsp;&nbsp;&nbsp;//更新out(讀者)的虛擬索引

&nbsp;&nbsp;&nbsp;&nbsp;fifo->out += len;

&nbsp;&nbsp;&nbsp;&nbsp;return len;
}


      從上面幾個(gè)重要的函數(shù)可以看出一些特性,就是put函數(shù)能放入的數(shù)據(jù)長(zhǎng)度永遠(yuǎn)不會(huì)大于緩沖區(qū)的長(zhǎng)度,而fifo->in - fifo->out永遠(yuǎn)小于等于size。
get函數(shù)得到的數(shù)據(jù)永遠(yuǎn)小于等于size(這個(gè)是必然的)。
在讀者/寫者問題中,發(fā)生互斥問題時(shí),使用環(huán)形隊(duì)列是很好的解決方案。
fifo不太好的地方在于,想寫完整的話,必須保證空間足夠大,否則不能保證一次寫完,特別是在中斷調(diào)用過程中,如果阻塞了,然后讓讀者讀取內(nèi)容后騰出空間喚醒繼續(xù)寫,將會(huì)出現(xiàn)問題,唯一我能想到的方法就是申請(qǐng)大空間,以避免這種“沒寫完”的情況發(fā)生。不知道還有沒有其它方法,寫的不對(duì)的地方,大家討論討論,我是菜鳥,寫得也倉促,剛寫內(nèi)核代碼不久,請(qǐng)多指教。

[ 本帖最后由 springtty 于 2009-3-24 00:04 編輯 ]

ldd3-5-1.png (7.74 KB, 下載次數(shù): 189)

ldd3-5-1.png

_kfifo_.pdf

145.2 KB, 下載次數(shù): 850


作者: dreamice    時(shí)間: 2009-03-23 12:30
不錯(cuò),整個(gè)pdf就好了
作者: Godbach    時(shí)間: 2009-03-23 13:13
分析的比較詳細(xì)。
作者: Godbach    時(shí)間: 2009-03-23 13:20
考慮到一個(gè)極限的情況啊。因?yàn)檫@里的in和out是一直增加的,那么當(dāng)存在in溢出,out還沒溢出的時(shí)候,是不是有一定的問題了?
    //注意,out 始終不會(huì)大于 in,(in - out)是有效數(shù)據(jù)空間大小,size是總空間的大小

    //那么空閑的空間大小就是 size - (int - out)

    //如果請(qǐng)求的len大于空閑空間,就使len = size - (int - out)

    len = min(len, fifo->size - fifo->in + fifo->out);

[ 本帖最后由 Godbach 于 2009-3-23 13:27 編輯 ]
作者: springtty    時(shí)間: 2009-03-23 23:51
原帖由 Godbach 于 2009-3-23 13:20 發(fā)表
考慮到一個(gè)極限的情況啊。因?yàn)檫@里的in和out是一直增加的,那么當(dāng)存在in溢出,out還沒溢出的時(shí)候,是不是有一定的問題了?

是的,就是考慮到這種情況。
謝謝各位老大的鼓勵(lì):)
作者: Godbach    時(shí)間: 2009-03-24 09:56
原帖由 springtty 于 2009-3-23 23:51 發(fā)表

是的,就是考慮到這種情況。
謝謝各位老大的鼓勵(lì):)


出現(xiàn)in溢出的時(shí)候:
    //如果請(qǐng)求的len大于空閑空間,就使len = size - (int - out)

    len = min(len, fifo->size - fifo->in + fifo->out);

這個(gè)結(jié)果還正確嗎?
作者: springtty    時(shí)間: 2009-03-25 12:56
原帖由 Godbach 于 2009-3-24 09:56 發(fā)表


出現(xiàn)in溢出的時(shí)候:

這個(gè)結(jié)果還正確嗎?

這里的in溢出而out沒有溢出是不是指 in(寫入)而out(讀。┑闹羔槶h(huán)繞的情況。
這里應(yīng)該避免這種情況,要不然就不能達(dá)到互斥訪問緩沖區(qū)的目的了。

[ 本帖最后由 springtty 于 2009-3-25 13:01 編輯 ]
作者: Godbach    時(shí)間: 2009-03-25 14:06
原帖由 springtty 于 2009-3-25 12:56 發(fā)表

這里的in溢出而out沒有溢出是不是指 in(寫入)而out(讀取)的指針環(huán)繞的情況。
這里應(yīng)該避免這種情況,要不然就不能達(dá)到互斥訪問緩沖區(qū)的目的了。


這里的in和out不都是unsigned int類型的嘛。而且你說out 不會(huì)大于in的。

那么當(dāng)出現(xiàn)in超過該類型的最大值時(shí),是不是溢出了,它的值是不是回繞到比較小的無符號(hào)整數(shù)了。
作者: springtty    時(shí)間: 2009-03-25 22:52
原帖由 Godbach 于 2009-3-25 14:06 發(fā)表


這里的in和out不都是unsigned int類型的嘛。而且你說out 不會(huì)大于in的。

那么當(dāng)出現(xiàn)in超過該類型的最大值時(shí),是不是溢出了,它的值是不是回繞到比較小的無符號(hào)整數(shù)了。

我理解錯(cuò)了,以為是buffer的溢出。
你說的情況確實(shí)存在,我只考慮數(shù)學(xué)層面上的東西了。
不過如果真的發(fā)生這種情況,程序還是正確的:
        unsigned int out        = 0xfffffff0;
        unsigned int in        = 0x00000006;
       
        printf("%u\n", in - out);
gcc打印出來的值等于22。

0x00000006
-0xfffffff0
================

0x00000016 = 22
作者: Godbach    時(shí)間: 2009-03-25 23:10
原帖由 springtty 于 2009-3-25 22:52 發(fā)表

我理解錯(cuò)了,以為是buffer的溢出。
你說的情況確實(shí)存在,我只考慮數(shù)學(xué)層面上的東西了。
不過如果真的發(fā)生這種情況,程序還是正確的:
        unsigned int out        = 0xfffffff0;
        unsigned int in        = 0x00000006;
...


buffer的話應(yīng)該不會(huì)溢出了,程序里面已經(jīng)控制好了。
在接著寫的時(shí)候,實(shí)際可寫的長(zhǎng)度通過如下代碼判斷,就算in是溢出的值,應(yīng)該也沒有問題。
len = min(len, fifo->size - fifo->in + fifo->out);

[ 本帖最后由 Godbach 于 2009-3-25 23:27 編輯 ]
作者: springtty    時(shí)間: 2009-03-25 23:42
原帖由 Godbach 于 2009-3-25 23:10 發(fā)表


buffer的話應(yīng)該不會(huì)溢出了,程序里面已經(jīng)控制好了。
在接著寫的時(shí)候,實(shí)際可寫的長(zhǎng)度通過如下代碼判斷,就算in是溢出的值,應(yīng)該也沒有問題。

kfifo的代碼雖短,但是蘊(yùn)含的東西卻很多。
我一直沒考慮到整數(shù)溢出的問題,看來以后自己寫代碼時(shí)得多加注意了。
作者: Godbach    時(shí)間: 2009-03-26 09:25
原帖由 springtty 于 2009-3-25 23:42 發(fā)表

kfifo的代碼雖短,但是蘊(yùn)含的東西卻很多。
我一直沒考慮到整數(shù)溢出的問題,看來以后自己寫代碼時(shí)得多加注意了。


呵呵,不過這里的溢出應(yīng)該不影響程序的預(yù)期結(jié)果
作者: epegasus    時(shí)間: 2009-03-26 09:52
環(huán)型緩沖是一種內(nèi)存管理方式,那改如何使用,使用的場(chǎng)景,以及和驅(qū)動(dòng)中銜接的接口是怎么樣的呢?
還煩請(qǐng)樓主做再接再厲
作者: springtty    時(shí)間: 2009-03-26 12:38
原帖由 epegasus 于 2009-3-26 09:52 發(fā)表
環(huán)型緩沖是一種內(nèi)存管理方式,那改如何使用,使用的場(chǎng)景,以及和驅(qū)動(dòng)中銜接的接口是怎么樣的呢?
還煩請(qǐng)樓主做再接再厲

好的,只是現(xiàn)在在寫論文,時(shí)間有點(diǎn)緊,等我我有空找點(diǎn)資料看看,再研究一下。
作者: emmoblin    時(shí)間: 2009-03-30 00:15
非常好的文章,看看linux環(huán)形緩沖區(qū)與我們自己寫的有什么區(qū)別
作者: 學(xué)習(xí)者_(dá)wyg    時(shí)間: 2009-04-01 22:43
提示: 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽
作者: connet    時(shí)間: 2009-04-08 10:15
很常用的 , 自己寫
一般in==out 時(shí), 把他們歸零。
作者: loryylx1    時(shí)間: 2009-05-14 10:27
學(xué)習(xí)下
作者: nehcc    時(shí)間: 2012-11-27 09:43
學(xué)習(xí)了
贊 。




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2