1

为什么我们需要semaphore条件变量s 和其他构造。我得到一个线程被阻塞,直到一个信号比一个接受mutex lock的线程好,检查一个如果没有通过的条件,解锁并重试直到条件通过
除此之外,还有没有其他好处。例如,我们可以只使用互斥锁来实现读写锁吗?如下所示:

int writers = 0;
int readers = 0;
mutex lock;

read_lock()
{
    mutex_lock(&lock);
    while(writers == 1)
    {
        mutex_unlock(&lock);  // unlock
        mutex_lock(&lock);    // retry
    }
    readers++;
    mutex_unlock(&lock);    
}

read_unlock()
{
    mutex_lock(&lock);
    readers--;
    mutex_unlock(&lock);
}

write_lock()
{
    mutex_lock(&lock);
    while(r>0 || w==1)
    {
        mutex_unlock(&lock);  // unlock
        mutex_lock(&lock);    // retry
    }
    writers++;
    mutex_unlock(&lock);      
}

write_unlock()
{
    mutex_lock(&lock);
    writers--;
    mutex_unlock(&lock);
}

1)上述实现是否可行?如果不是,为什么?
2)我可以说多线程中的所有事情都可以只使用互斥锁来完成吗?

4

2 回答 2

1

互斥锁旨在为共享(线程之间)变量提供保护。它并非旨在提供同步。

我将尝试举一个例子。假设我们有一个需要共享的链表,我们需要启动 10 个线程——其中 5 个线程负责写入链表,其中 5 个线程负责负责从链表中读取。我们必须将链表视为一个队列(FIFO)——写入链表的末尾,从链表的前端读取所有线程都需要独占访问链表(因为读取器会从队列的头部移除项目作为写入者添加到队列的尾部)并且还有一个随机的计算延迟(或者只是假设他们需要睡眠) 现在的问题:我们如何确保队列头部和尾部的完整性?

似乎不可能只使用互斥锁吗?这就是为什么 NO , mutex 在所有情况下都不够。

在我的情况下,我们需要一个条件变量使用这些变量并通过广播(甚至单独)通知其他线程,我们将能够实现线程之间的同步,确保我们共享的头部和脚部的完整性。

PS:另一个好的观点是这个。 附言

于 2018-08-24T10:14:50.580 回答
0

回复,“为什么我们需要......构造?”

因为,抽象层代码重用

例如,您不需要有一个阻塞队列。如果您有数组和指针以及互斥锁和条件变量,那么您可以使用它们来实现您可以使用阻塞队列实现的任何东西。但是您的代码将更难阅读,因为在您可以调用q.put(...)or的每个地方,您q.take()都必须编写一大堆代码。

阻塞队列是一种有用的抽象:它将较低级别的想法包装成一个更简单、更高级别的函数。

如果您有阻塞队列,则不需要信号量。你可以用信号量做任何事情,你可以通过将无意义的标记放入队列然后删除它们来完成。信号量确实是队列思想的更简单版本,它可能更适合(更好地描述)您要解决的问题。

此外,您不需要使用任何其他人的阻塞队列或信号量实现:您始终可以编写自己的,但为什么要做额外的工作?(除了,也许是为了教育目的。)

于 2018-08-24T14:11:33.310 回答