为什么另一个线程,比如 B 运行 当 pthread_mutex 在线程 A 中被锁定和解锁时?

Why is another thread, say B running when pthread_mutex is being locked and unlocked inside thread A?

根据手册页

pthread_mutex_lock locks the given mutex. If the mutex is currently unlocked, it becomes locked and owned by the calling thread, and pthread_mutex_lock returns immediately. If the mutex is already locked by another thread, pthread_mutex_lock suspends the calling thread until the mutex is unlocked.

我的理解是当 line 3 执行 main thread 时拥有 mtx 的所有权。然后它执行其关键区域操作,然后到达 line 4 并解锁 mtx。我的问题是 -

  1. mtx被锁定时,另一个线程是否可以并发运行?
  2. line 2有什么用,因为newThread只能在line 4执行后才能解锁mtx,从而使line 2变得多余?
  3. 如果 line 1 取消注释会怎样?

    #include<stdio.h>
    #include<pthread.h>
    #include<semaphore.h>
    #include<unistd.h>
    
    
    sem_t bin_sem;
    pthread_mutex_t mtx;
    char message[100];
    
    
    void * thread_function(void * arg)
    {   
        int x;
        char message2[10];
        while(1)
        {   
    
    //      pthread_mutex_lock(&mtx); //line 1
            printf("thread2 : waiting..\n\n");
            sem_wait(&bin_sem);     
            printf("hi i am the new thread waiting inside critical..\n");
            scanf("%s",message);
            printf("You entered in newthread:%s\n\n",message);
            sem_post(&bin_sem);
            pthread_mutex_unlock(&mtx); //line 2
    
        }
    
    }
    
    int main(void)
    {
        pthread_t athread;
        pthread_attr_t ta;
        char message2[10];
        int x;
    
        sem_init(&bin_sem,0,1);
    
        pthread_mutex_init(&mtx,NULL);
    
        pthread_attr_init(&ta);
        pthread_attr_setschedpolicy(&ta,SCHED_RR);                                                                                                                                                                                                       
    
        pthread_create(&athread,&ta,thread_function,NULL);
        while(1)
        {   
            pthread_mutex_lock(&mtx); //line 3
            printf("main waiting..\n\n");
            sem_wait(&bin_sem); 
            printf("hi i am the main thread waiting inside critical..\n");
            scanf("%s",message);
            printf("You entered in main:%s\n\n",message);
            sem_post(&bin_sem);
            pthread_mutex_unlock(&mtx); //line 4
        }
        sleep(5);       
    }
    

互斥一种实现临界区的机制。

pthread_mutex_lock(x)pthread_mutex_unlock(x) 调用之间的任何代码在任何给定时间都将仅在一个线程中执行。就这些了。

所以...

1. Can the other thread concurrently run when mtx is locked?

如果它没有锁定 mtx,那当然可以。

2. What is the use of line 2 since newThread can only unlock mtx when line 4 has been executed, and thus makes line 2 redundant?

互斥体变得无用,并且您还会得到 UB,因为您在未锁定它的线程中解锁它:

If the mutex type is PTHREAD_MUTEX_DEFAULT...
Attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior.

(默认情况下你得到互斥类型PTHREAD_MUTEX_DEFAULT

3. What would happen if line 1 is uncommented?

你得到 thread starvation,因为互斥量几乎一直处于锁定状态,并且在解锁后立即重新锁定(POSIX 不能保证互斥量的公平性)。

A POSIX semaphore does provide fairness in some cases (when you use SCHED_FIFO or SCHED_RR schedulers), but is heavier.

我不太明白你想达到什么目的(应用程序看起来做作)。在实际应用程序中,任一线程需要执行的操作可能有一些逻辑顺序。因此,如果信号量适合您,我会保留它并删除互斥量。