ความแตกต่างระหว่างการแยกร่วมกันและ blocked-IO ในการเขียนโปรแกรมเคอร์เนล?

ฉันไม่สามารถเข้าใจความแตกต่างระหว่างสองรหัสต่อไปนี้ เนื้อหาใดสามารถอธิบายความแตกต่างระหว่างรหัสต่อไปนี้ & อธิบายความแตกต่างระหว่างเซมาฟอร์และ mutex พร้อมตัวอย่างได้ ....

การกีดกันซึ่งกันและกัน:

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;
}

person Sandy    schedule 04.10.2013    source แหล่งที่มา
comment
ข้อแตกต่างก็คือโค้ดที่สองนั้นบั๊กมาก และไม่สามารถคอมไพล์ได้ มันมาจากไหน?   -  person CL.    schedule 04.10.2013
comment
ใช้เซมาฟอร์โครงสร้างแบบคงที่ mysem = __SEMAPHORE_INITIALIZER(mysem,0) insted of init_MUTEX_LOCKED(&mysem)   -  person Sandy    schedule 04.10.2013


คำตอบ (1)


Mutex ไม่มีอะไรนอกจากเซมาฟอร์ไบนารี หมายความว่า mutex สามารถมีได้เพียงสองสถานะ: ล็อคและปลดล็อค แต่เซมาฟอร์สามารถมีได้มากกว่าสองครั้ง ดังนั้นจำนวนกระบวนการที่สามารถรับการล็อคเซมาฟอร์ได้จึงเท่ากับจำนวนที่เซมาฟอร์เริ่มต้นใช้งาน

ในตัวอย่างของคุณ ในตัวอย่างโค้ดแรก ไม่ว่าจะอ่านหรือเขียนก็ตาม ขึ้นอยู่กับว่าฝ่ายใดได้รับการล็อคตัวมันเองจะปล่อยการล็อคหลังจากที่อ่านหรือเขียนตามลำดับเสร็จแล้ว ทั้งสองไม่สามารถทำงานพร้อมกันได้เนื่องจาก mutex

ในขณะที่อยู่ในข้อมูลโค้ดที่สอง โค้ดจะแสดงแนวคิดการบล็อก I/O ซึ่งได้รับการออกแบบมาเพื่อแก้ปัญหาที่อธิบายไว้ในหนังสือ Linux Device Drivers (LDD) : "จะทำอย่างไรเมื่อยังไม่มีข้อมูลให้อ่าน แต่เรายังไม่ได้อ่าน สิ้นสุดไฟล์ คำตอบเริ่มต้นคือเข้าสู่โหมดสลีปเพื่อรอข้อมูล" ดังที่คุณเห็นในโค้ด การล็อกถูกประกาศเป็น Mutex และอยู่ในสถานะล็อกด้วย ดังนั้น หากมีการอ่านใด ๆ เกิดขึ้นเมื่อไม่มีข้อมูล จะไม่สามารถรับการล็อคได้ เนื่องจาก mutex อยู่ในสถานะล็อคแล้ว ดังนั้นการอ่านจะเข้าสู่โหมดสลีป (สรุปว่าการอ่านถูกบล็อก) เมื่อใดก็ตามที่มีการเขียนใดๆ เข้ามา อุปกรณ์จะเขียนลงในอุปกรณ์ก่อน จากนั้นจึงปล่อย mutex ดังนั้น ขณะนี้การอ่านที่ถูกบล็อกสามารถรับการล็อคนั้นและสามารถดำเนินการอ่านให้เสร็จสิ้นได้ ที่นี่ทั้งคู่ไม่สามารถทำงานพร้อมกันได้ แต่กลไกการรับและปลดล็อคล็อคจะถูกซิงโครไนซ์ในลักษณะที่การอ่านไม่สามารถคืบหน้าได้จนกว่าการเขียนจะไม่เขียนอะไรลงในอุปกรณ์

person pratik    schedule 04.10.2013