C 互斥锁是锁定的,但其他线程正在进入关键部分

C 互斥锁是锁定的,但其他线程正在进入关键部分,c,multithreading,operating-system,pthreads,mutex,C,Multithreading,Operating System,Pthreads,Mutex,我们已经研究过,如果我们处理多线程问题,那么我们使用一种称为互斥的线程同步方法,该方法允许锁定关键部分,以便其他线程不会干扰并进入块状态,直到互斥解锁关键部分 但是我在我的程序中做这件事,但是这个程序的输出与互斥的概念不匹配。如果我错了,请纠正我 代码 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <signal.h> #include <pthread

我们已经研究过,如果我们处理多线程问题,那么我们使用一种称为互斥的线程同步方法,该方法允许锁定关键部分,以便其他线程不会干扰并进入块状态,直到互斥解锁关键部分

但是我在我的程序中做这件事,但是这个程序的输出与互斥的概念不匹配。如果我错了,请纠正我

代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>

#define MAX 10 

pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
int toConsume=0;
int i;

void* consumer(void *ptr) {
pthread_mutex_lock(&the_mutex);
while(i<MAX)
{
    /* protect buffer */
    while (toConsume <= 0) /* If there is nothing in the buffer then  wait */
    {
        printf("Waiting Thread id:%lu \n",pthread_self());
        pthread_cond_wait(&condc, &the_mutex);
    }
   pthread_mutex_unlock(&the_mutex); /* release the buffer */

    sleep(2);

   pthread_mutex_lock(&the_mutex); /* protect buffer */
   toConsume--;
   i++;
 }
 pthread_mutex_unlock(&the_mutex); /* release the buffer */
 pthread_exit(0);
}

int main(int argc, char **argv) {
pthread_t pro, con[3];
pthread_mutex_init(&the_mutex, NULL);
pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */
pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */

// Create the threads

for(int i=0 ;i<3;i++)
pthread_create(&con[i], NULL, consumer, NULL);

for(int i=0 ;i<3;i++)
pthread_join(con[i], NULL);

return 0;
}

所有线程都进入临界区,即使互斥锁保持锁定。

函数
pthread\u cond\u wait
将在线程等待时解锁保持的互斥锁。这允许另一个线程进入临界段

使用
pthread\u cond\u wait
的目的是,线程需要等待某个条件变为真,然后才能真正执行关键部分内的工作。要首先测试条件,需要锁定互斥锁。但是,如果条件为false,它必须等待某个事件使条件为true。如果它在保持锁的情况下等待,则没有其他线程能够更新状态以使条件变为true,因为更新条件还需要锁定相同的互斥锁

因此,当等待条件变量时,互斥锁被解锁,以允许另一个线程获取锁来执行使条件为真的操作

作为一个例子,考虑一个作业队列。线程将锁定互斥锁以从队列中获取作业。但是,如果队列为空,则必须等待作业出现在队列中。这是必须等待的条件,可以使用条件变量来实现此目的。当它在条件变量上调用

pthread\u cond\u wait
时,关联的互斥锁被解锁

另一个线程希望将作业放入队列。该线程可以锁定互斥锁,将作业添加到队列,向条件变量发送信号,然后解锁互斥锁


当条件变量发出信号时,等待的线程被唤醒,
pthread\u cond\u wait
返回并再次保持互斥锁。它检测到队列非空,并可以进入将作业从队列中移出队列的关键部分。

此解释澄清了我的概念,但是否有任何方法可以停止在关键部分输入其他线程,即使其他线程正在等待某些条件变为真。@suleman:它们已停止,因为它们必须等待相同的条件变为真。现在让我们假设所有线程都处于等待状态,突然一个作业进入队列,其中有一段等待时间,此时条件变为真,一个线程接受该作业并使用sleep(waiting_time)函数执行一些等待,此时,另一个作业到达队列,并且通过信令条件再次变为真,此时,第二个线程也将接受第一个线程提供服务的第一个作业。请澄清这一误解。@suleman:critical部分从队列中删除第一个作业。任何进入临界区的后续线程都不会看到该作业。@suleman:一次只有一个线程可以在互斥锁上持有锁,因此即使有多个线程在条件变量上唤醒,每个线程每次只能从
pthread\u cond\u wait
返回一个线程,当互斥锁变为可锁定时。告诉我
pthread\u cond\u wait
做了什么。它将通过使用来自其他进程或线程的信号来等待某些条件变为真。在循环内锁定互斥锁并在循环外相应解锁通常是个坏主意——在
consumer()
函数中,如果
在(我故意把它放入循环中。@suleman就是它所做的一切吗?(提示:否)
$ ./ex
Waiting Thread id:140580582618880 
Waiting Thread id:140580574226176 
Waiting Thread id:140580565833472