Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为什么要使用pthread_mutex_lock,而这可以通过可编程的方式实现?_Linux_Pthreads_Critical Section - Fatal编程技术网

Linux 为什么要使用pthread_mutex_lock,而这可以通过可编程的方式实现?

Linux 为什么要使用pthread_mutex_lock,而这可以通过可编程的方式实现?,linux,pthreads,critical-section,Linux,Pthreads,Critical Section,我们都知道信号量和临界截面问题 在pthreads中,这可以通过使用pthread\u mutex\u lock()和pthread\u mutex\u unlock()进行排序 但是,我们为什么需要这些系统调用,而这些调用可以在代码中实现,比如: flag = 0; if (flag) // Thread1 enters and makes flag = 0 { flag = 0; // On entering critical section, flag is made 0 so th

我们都知道信号量和临界截面问题

在pthreads中,这可以通过使用
pthread\u mutex\u lock()
pthread\u mutex\u unlock()
进行排序

但是,我们为什么需要这些系统调用,而这些调用可以在代码中实现,比如:

flag = 0;
if (flag) // Thread1 enters and makes flag = 0
{
   flag = 0; // On entering critical section, flag is made 0 so that others can't enter
  // do some critical section operation
  flag = 1;
}
// Thread1 exits

如上所述,它能解决临界截面问题吗?如果没有,那么为什么?

首先,如果代码可以工作,第二个线程将完全跳过关键部分。你得在那里放一个环什么的


另外,要考虑到调度程序可能会在任何地方抢占您的线程。如果线程A进行测试并在更改
标志之前被抢占,而线程B被允许进行测试并随后进入被抢占的关键部分,会发生什么情况。您将有两个线程。

首先,如果您的代码可以工作,第二个线程将完全跳过关键部分。你得在那里放一个环什么的


另外,要考虑到调度程序可能会在任何地方抢占您的线程。如果线程A进行测试并在更改
标志之前被抢占,而线程B被允许进行测试并随后进入被抢占的关键部分,会发生什么情况。您将有两个线程。

首先,您应该使用原子内存操作(请参阅MSVC中的InterlockedCompareeExchange()和GCC中的uu sync\u val\u compare\u和_swap()


其次,这段代码可以工作,但前提是当第一个线程将标志设置回1时,第二个线程不应该等待。如果应该,您将以循环结束,这将消耗您所有的CPU。在这种情况下,您应该使用一些会导致等待的线程睡眠的东西(例如pthread_mutex_lock())。

首先,您应该使用原子内存操作(请参阅MSVC中的InterlockedCompareeExchange()和GCC中的uu sync_val_compare_和swap()


其次,这段代码可以工作,但前提是当第一个线程将标志设置回1时,第二个线程不应该等待。如果应该,您将以循环结束,这将消耗您所有的CPU。在这种情况下,您应该使用一些会导致等待线程睡眠的东西(例如pthread_mutex_lock())。

既然您已经用“linux”标记了您的问题,您可能会补充说pthread是在名为“futex”或“快速用户空间mutex”的东西之上构建的。顾名思义,快速路径,即锁定和解锁非竞争互斥体,不需要系统调用,而是在用户空间中完成的。FWIW,AFAIK Windows也做了类似的事情。

既然您已经用“linux”标记了您的问题,您可能会补充说pthread是建立在所谓的“Futex”或“快速用户空间互斥体”之上的。顾名思义,快速路径,即锁定和解锁非竞争互斥体,不需要系统调用,而是在用户空间中完成的。FWIW,AFAIK Windows也做了类似的事情。

可能有很多原因导致使用
pthread\u mutex
对象和操作这些对象的API,而不是每个人编写自己的同步原语。一对更重要的:

  • 与许多其他对广泛受众有用的对象和功能一样,标准化这些功能是有意义的,这样人们就不必重新发明轮子,就可以使用和识别标准模式和习惯用法。换句话说,存在pthread互斥体api的原因与存在标准字符串操作函数的原因相同

  • 众所周知,同步技术非常复杂,而且很难正确使用。因此,最好有一个经过审查的代码库来执行此功能。即使可以无数次地重新发明轮子,但有99%的实现存在严重缺陷也不是一个好情况。例如,pthreads处理诸如内存障碍和原子性之类的问题,这些问题在您的问题示例中没有得到正确的解决。考虑问题中的例子:至少有一个严重问题;它有一个争用条件,其中两个线程可以同时进入临界段,因为
    标志的测试和将其设置为0不是自动执行的


    • 使用
      pthread\u mutex
      对象和操作这些对象的API,而不是每个人编写自己的同步原语,可能有很多原因。一对更重要的:

      • 与许多其他对广泛受众有用的对象和功能一样,标准化这些功能是有意义的,这样人们就不必重新发明轮子,就可以使用和识别标准模式和习惯用法。换句话说,存在pthread互斥体api的原因与存在标准字符串操作函数的原因相同

      • 众所周知,同步技术非常复杂,而且很难正确使用。因此,最好有一个经过审查的代码库来执行此功能。即使可以无数次地重新发明轮子,但有99%的实现存在严重缺陷也不是一个好情况。例如,pthreads处理诸如内存障碍和原子性之类的问题,这些问题在您的问题示例中没有得到正确的解决。考虑问题中的例子:至少有一个严重问题;它有一个争用条件,其中两个线程可以同时进入临界段,因为
        标志的测试和将其设置为0不是自动执行的


      线程A进行测试,并在更改标志之前被抢占
      在这种情况下,线程B处于关键部分,而不是A,对吗?因此,当threadA返回时,它看到标志是等待,因为threadB在那里,所以它等待。那么问题出在哪里呢?sched几乎可以随时暂停线程