【问题标题】:Implementing locks实现锁
【发布时间】:2021-06-18 19:38:24
【问题描述】:

阅读implementing locks的操作系统资料时的一些疑惑

struct lock {
    int locked;
    struct queue q;
    int sync;         /* Normally 0. */
};

void lock_acquire(struct lock *l) {
    intr_disable();
    while (swap(&l->sync, 1) != 0) {
        /* Do nothing */
    }
    if (!l->locked) {
        l->locked = 1;
        l->sync = 0;
    } else {
        queue_add(&l->q, thread_current());
        thread_block(&l->sync);
    }
    intr_enable();
}

void lock_release(struct lock *l) {
    intr_disable();
    while (swap(&l->sync, 1) != 0) {
        /* Do nothing */
    }
    if (queue_empty(&l->q) {
        l->locked = 0;
    } else {
        thread_unblock(queue_remove(&l->q));
    }
    l->sync = 0;
    intr_enable();
}

sync的目的是什么?

【问题讨论】:

  • 是的,队列通常是 FIFO 数据结构,您发布的代码 sn-p 似乎也是如此。

标签: c multithreading operating-system


【解决方案1】:

在我看来,“同步”是线程让操作系统知道锁正在使用中的一种方式,因为机器人“锁定”和“解锁”在继续之前等待“同步”值更改。

(在检查“同步”值之前禁用中断有点奇怪)

【讨论】:

    【解决方案2】:

    我的直觉是解决方案都被打破了。对于正常工作的锁,lock_acquire 需要具有获取语义,而 lock_release 需要具有释放语义。这样,临界区内部的加载/存储就不能移出临界区 + 在锁定释放和后续锁定同一锁定获取之间的边缘之前发生。

    如果你看一下旋转版本:

    struct lock {
       int locked;
    };
    
    void lock_acquire(struct lock *l) {
        while (swap(&l->locked, 1)) {
            /* Do nothing */
        }
    }
    
    void lock_release(struct lock *l) {
         l->locked = 0;
    }
    

    locked=0 的赋值只是普通的存储。这意味着它可以在它之前与其他加载和存储一起重新排序 + 它不提供发生在边缘之前。

    【讨论】:

      猜你喜欢
      • 2014-08-26
      • 2018-03-17
      • 2019-05-19
      • 1970-01-01
      • 2015-12-27
      • 2017-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多