Почему другой поток, скажем B, работает, когда pthread_mutex заблокирован и разблокирован внутри потока A? - PullRequest
0 голосов
/ 28 ноября 2018

Согласно справочным страницам

pthread_mutex_lock блокирует указанный мьютекс.Если мьютекс в настоящее время разблокирован, он становится заблокированным и принадлежит вызывающему потоку, и pthread_mutex_lock немедленно возвращается.Если мьютекс уже заблокирован другим потоком, pthread_mutex_lock приостанавливает вызывающий поток, пока мьютекс не будет разблокирован.

Я понял, что когда line 3 выполняет, main thread владеет mtx,Затем он выполняет свои действия в критической области, затем достигает line 4 и разблокирует mtx.У меня вопрос -

  1. Может ли другой поток выполняться одновременно, когда mtx заблокирован?
  2. Какая польза от line 2, поскольку newThread может разблокировать только mtxкогда line 4 был выполнен и, таким образом, делает 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);       
    }
    

1 Ответ

0 голосов
/ 28 ноября 2018

Мьютекс - это механизм реализации критических секций.

Любой код между вызовами pthread_mutex_lock(x) и pthread_mutex_unlock(x) будет выполняться только в одном потоке в любой момент времени.Вот и все.

Итак ...

1.Может ли другой поток одновременно выполняться, когда mtx заблокирован?

Если он не заблокировал mtx, тогда, конечно.

2.Какая польза от строки 2, поскольку newThread может разблокировать mtx только тогда, когда строка 4 была выполнена, и, таким образом, делает строку 2 избыточной?

Мьютекс становится бесполезным, и вы также получаете UB , поскольку вы разблокируете его в потоке, который его не блокировал:

Если тип мьютекса - PTHREAD_MUTEX_DEFAULT ...
Попытка разблокировать мьютекс, еслион не был заблокирован вызывающим потоком, что приводит к неопределенному поведению.

(по умолчанию вы получаете тип мьютекса PTHREAD_MUTEX_DEFAULT)

3.Что произойдет, если строка 1 не закомментирована?

Вы получите thread голодание , так как мьютекс блокируется почти все время и немедленноблокируется после разблокировки (POSIX не гарантирует справедливость мьютекса).

Семафор POSIX в некоторых случаях обеспечивает справедливость (при использовании планировщиков SCHED_FIFO или SCHED_RR),но тяжелее .

Я не совсем понимаю, чего вы пытаетесь достичь (приложение выглядит надуманным).В реальном приложении, вероятно, существует некий логический порядок действий, которые должен выполнить любой поток.Поэтому, если у вас работает семафор, я бы сохранил его и удалил мьютекс.

...