2013-10-04 30 views
0

我無法理解以下兩個代碼之間的區別。任何機構可以解釋以下碼之間的差也&解釋旗語,並用實施例互斥之間的差異性....內核編程中互斥和阻塞IO的區別?

互斥:

DEFINE_SEMAPHORE(mysem); 
static ssize_t dev_read(struct file *file,char *buf, size_t lbuf, loff_t *ppos) 
{ 
    int maxbytes, bytes_to_do, nbytes; 
    maxbytes = SIZE - *ppos; 
    if(maxbytes < lbuf) bytes_to_do = maxbytes; 
    else bytes_to_do = lbuf; 
    if(bytes_to_do == 0){ 
     printk("reached end of device\n"); 
     return -ENOSPC; 
    } 
    if(down_interruptible(&mysem)) 
     return -ERESTARTSYS; 
    nbytes = bytes_to_do - copy_to_user(buf,dev_buf+*ppos,bytes_to_do); 
    up(&mysem); 
    *ppos += nbytes; 
    return nbytes; 
} 
static ssize_t dev_write(struct file *file,const char *buf, size_t lbuf, 
          loff_t *ppos) 
{ 
    int maxbytes, bytes_to_do, nbytes; 
    maxbytes = SIZE - *ppos; 
    if(maxbytes < lbuf) bytes_to_do = maxbytes; 
    else bytes_to_do = lbuf; 
    if(bytes_to_do == 0){ 
     printk("reached end of device\n"); 
     return -ENOSPC; 
    } 
    if(down_interruptible(&mysem)) 
     return -ERESTARTSYS; 
    nbytes = bytes_to_do - copy_from_user(dev_buf+*ppos,buf,bytes_to_do); 
    ssleep(10); 
    up(&mysem); 
    *ppos += nbytes; 
    return nbytes; 
} 

阻止IO

init_MUTEX_LOCKED(&mysem); 
static ssize_t dev_read(struct file *file,char *buf, size_t lbuf, loff_t *ppos) 
{ 
    int maxbytes, bytes_to_do, nbytes; 
    maxbytes = SIZE - *ppos; 
    if(maxbytes < lbuf) bytes_to_do = maxbytes; 
    else bytes_to_do = lbuf; 
    if(bytes_to_do == 0){ 
     printk("reached end of device\n"); 
     return -ENOSPC; 
    } 
    if(down_interruptible(&mysem)) 
     return -ERESTARTSYS; 
    nbytes = bytes_to_do - copy_to_user(buf,dev_buf+*ppos,bytes_to_do); 
    *ppos += nbytes; 
    return nbytes; 
} 
static ssize_t dev_write(struct file *file,const char *buf, size_t lbuf, 
          loff_t *ppos) 
{ 
    int maxbytes, bytes_to_do, nbytes; 
    maxbytes = SIZE - *ppos; 
    if(maxbytes < lbuf) bytes_to_do = maxbytes; 
    else bytes_to_do = lbuf; 
    if(bytes_to_do == 0){ 
     printk("reached end of device\n"); 
     return -ENOSPC; 
    } 
    nbytes = bytes_to_do - copy_from_user(dev_buf+*ppos,buf,bytes_to_do); 
    ssleep(10); 
    up(&mysem); 
    *ppos += nbytes; 
    return nbytes; 
} 
+0

不同的是,第二個代碼是可怕的錯誤,不會編譯。它從何而來? –

+0

使用 static struct semaphore mysem = __SEMAPHORE_INITIALIZER(mysem,0)insted init_MUTEX_LOCKED(&mysem) – Sandy

回答

2

互斥量不過是一個二進制信號量。這意味着互斥鎖只能有兩種狀態:鎖定和解鎖。但信號量可以有兩個以上的計數。所以可以獲取信號量鎖的進程數量等於信號量初始化的次數。

在您的示例中,在第一個代碼段中,無論是讀取還是寫入,取得鎖的哪一個本身都會在完成其各自的讀取或寫入後釋放鎖。由於互斥體,兩者不能同時工作。

在第二個代碼片段中,代碼展示了阻塞I/O概念,該概念旨在解決Linux設備驅動程序(Linux Device Drivers,LDD)中描述的問題:「當沒有數據尚未讀取時該怎麼辦,但我們'不在文件結尾,默認的答案是進入休眠等待數據「。正如你在代碼中看到的那樣,lock被聲明爲Mutex並且也處於鎖定狀態。所以,如果在沒有數據的情況下讀取數據,它就不能獲取鎖定,因爲互斥鎖已經處於鎖定狀態,所以它會進入休眠狀態(簡而言之,讀取被阻止)。無論何時寫入,它首先寫入設備,然後釋放互斥鎖。所以,現在被阻止的讀取可以獲得該鎖並可以完成其讀取過程。在這裏,兩者不能同時工作,但是鎖定獲取和釋放機制是以這樣的方式同步的,即在寫入不向設備寫入任何內容之前讀取不能進行。