Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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
C++ 为什么';在我的其他线程锁定互斥锁之前,我的互斥锁不会被锁定吗?_C++_C_Multithreading_Pthreads_Mutex - Fatal编程技术网

C++ 为什么';在我的其他线程锁定互斥锁之前,我的互斥锁不会被锁定吗?

C++ 为什么';在我的其他线程锁定互斥锁之前,我的互斥锁不会被锁定吗?,c++,c,multithreading,pthreads,mutex,C++,C,Multithreading,Pthreads,Mutex,我正在运行一个用pthreads创建的线程,并且在线程和主线程之间使用互斥锁。据我所知,一旦线程准备好锁定互斥锁,它将自旋锁定,直到能够锁定为止。但我遇到了一个问题,它不会自锁。我的伪代码 主线程: //I create thread 1 on this line, then it enters the while loop while(p.size() > r.size()){ pthread_mutex_lock(&Mutex); //calculations and

我正在运行一个用pthreads创建的线程,并且在线程和主线程之间使用互斥锁。据我所知,一旦线程准备好锁定互斥锁,它将自旋锁定,直到能够锁定为止。但我遇到了一个问题,它不会自锁。我的伪代码

主线程:

//I create thread 1 on this line, then it enters the while loop
while(p.size() > r.size()){
  pthread_mutex_lock(&Mutex);
  //calculations and decrease p.size()
  pthread_mutex_unlock(&Mutex);
}
线程1:

//wait 500ms before hitting mutex
pthread_mutex_lock(&Mutex);
//calculations
pthread_mutex_unlock(&Mutex);
我运行的问题是,线程1互斥体在主线程while循环退出之前从不锁定。线程1在主线程完成while循环之前到达互斥锁


编辑:如果我在while循环结束时有10毫秒的延迟(在互斥锁解锁之后),那么这就解决了我的问题。但是我如何才能在不增加10毫秒延迟的情况下解决问题。

您的主线程正在解锁互斥锁,然后立即再次锁定它。尝试在主循环中引入延迟(出于测试目的),看看这是否是问题所在

查看此问题的答案:

C标准没有定义
sleep
函数,我相信Posix
sleep
函数以秒为参数。@user3386109 sleep函数是不相关的,只需在命中互斥对象之前假设线程延迟。超越sleep()中的潜在错误即可。对于Windows本机线程和本机互斥体,通常获取的锁的顺序与请求的顺序相同。在其他环境中,可能不会指定授予的锁的顺序,并且同一线程可能会不断获取锁,即使多个线程正在等待尝试获取锁。在某些情况下,发生这种情况的原因是,使用unlock()lock()序列执行循环的线程是当前正在运行的线程,因此它再次获取互斥,并且没有发生上下文切换。可能系统需要启动并计划新线程执行的时间太长,但还不清楚问题出在哪里。如果线程1应该在主线程进入循环之前完成,那么为什么要在一个单独的线程中进行计算呢?非常感谢,我不知道操作系统会这么快地运行线程,从而跳过其他线程。我需要使用一个条件变量。谢谢你和评论中的其他人,他们帮助我解决了这个问题。谢谢。@JDoe4444-这是一个依赖操作系统的问题。如上所述,在Windows(和其他操作系统)使用本机同步接口的情况下,使用内部队列(或等效队列)对请求进行排序,从而消除了此类问题或必须处理虚假唤醒。对于这些操作系统来说,快速重新锁定不是问题,因为需要排队强制上下文切换以保持请求的顺序。@JDoe4444,您假设互斥锁是作为旋转锁实现的,但对于在多任务操作系统上运行的通用互斥锁实现来说,这是不实际的。如果您的
thread1
被阻塞了很长时间,那么操作系统将使其进入睡眠状态。然后,当主线程释放互斥锁并立即再次尝试锁定它时,睡眠线程和已经在内存中并正在运行的线程之间就会发生竞争。除非它是所谓的“公平”互斥体,否则已经运行的线程将永远赢得这场竞赛。