Какой из них верен в использовании функции pthread_mutex_lock ()? - PullRequest
1 голос
/ 13 июля 2020

Я изучаю, как использовать глобальные переменные через многопоточность, но сейчас у меня проблема: примерно pthread_mutex_lock() и pthread_mutex_unlock().

Правильно ли используется в function1 или function2? Если нет, то как его правильно использовать?

В то время я только что изменил один из элементов массива. Например, после того, как thread1 изменилось AllSensorInfoArray[2][66].sensorType, thread1 изменится AllSensorInfoArray[2][67].sensorType, теперь thread2 может изменить AllSensorInfoArray[2][66].sensorType. Другими словами, несколько потоков не могут изменять AllSensorInfoArray[2][66].sensorType одновременно.

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

pthread_mutex_t AllSensorMutex;

void *function1(void *arg)
{


    int t = 0, i = 0;
    /*
        some codes
    */
    pthread_mutex_lock(&AllSensorMutex);
    for (t = 0; t < 100; t++)
    {
        AllSensorInfoArray[i][t].sensorType = allData[2+t];
    }
    pthread_mutex_unlock(&AllSensorMutex);
    /*
        some codes
    */
}

void *function2(void *arg)
{

    /*
        some codes
    */
    int t = 0, i = 0;
    for (t = 0; t < 100; t++)
    {
        pthread_mutex_lock(&AllSensorMutex);
        AllSensorInfoArray[i][t].sensorType = allData[2+t];
        pthread_mutex_unlock(&AllSensorMutex);
    }
    /*
        some codes
    */
}

int main(void)
{
    while(pthread_mutex_init(&AllSensorMutex, NULL))
    {
        printf("(%s) write mutex init error!\n", __FUNCTION__);
        sleep(1);
    }

    pthread_t thread1;
    pthread_t thread2;
    int ret = pthread_create(&thread1, NULL, function1, NULL);
    if (ret != 0)
    {
        printf("(%s) failed to create a pthread, return error code : %d.\n", __FUNCTION__, ret);
        exit(-1);
    }

    ret = pthread_create(&thread2, NULL, function2, NULL);
    if (ret != 0)
    {
        printf("(%s) failed to create a pthread, return error code : %d.\n", __FUNCTION__, ret);
        exit(-1);
    }
    while (1)
    {
        sleep(1);
    }
}

1 Ответ

0 голосов
/ 13 июля 2020

Правильно ли использование в function1 или function2?

Оба значения одинаково верны и будут работать. Первый вариант «лучше» для этого конкретного случая.

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

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

for (i = 0; i < sensor_count; i++) {
    value = read_sensor(i);

    pthread_mutex_lock(&mutex);
    sensor_reading[i] = value;
    pthread_mutex_unlock(&mutex);
}

вместо pthread_mutex_lock(&mutex); sensor_reading[i] = read_sensor(i); pthread_mutex_unlock(&mutex);, потому что последний будет просто удерживать мьютекс во время чтения датчика, блокируя доступ других потоков к массиву на время вызова read_sensor(i) без разумной причины.

Простое присвоение или арифметика c для элемента массива не 'медленное ', и поэтому здесь рекомендуется использовать первую функцию.

В общем, шаблон

for (i = 0; i < N; i++) {
    pthread_mutex_lock(&mutex);

    /* Do something */

    pthread_mutex_unlock(&mutex);
}

освобождает мьютекс только на короткое время, и в зависимости от реализации pthreads он может быть недостаточно длинным для любого другого потока, чтобы захватить мьютекс, даже если они уже блокировали / ожидали мьютекса (в вызове pthread_mutex_lock (& ​​mutex)). Это не является неправильным или ошибочным, но он просто работает так же, как

pthread_mutex_lock(&mutex);
for (i = 0; i < N; i++) {

    /* Do something */

}
pthread_mutex_unlock(&mutex);

, и менее эффективен, чем эта последняя форма, потому что первая делает (N -1) дополнительный pthread_mutex_lock () и pthread_mutex_unlock (), без каких-либо гарантий каких-либо преимуществ от этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...