Безопасно ли создавать поток с помощью pthread_create, когда std :: lock_guard все еще находится в области видимости? - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть функция, подобная следующей, в которой потоки получают блокировку с помощью std::lock_guard мьютекса и записывают в файл с помощью ofstream.

Когда текущий размер файла увеличивает максимальный размер, я хочу создать независимый поток, который должен сжать файл и завершиться.

Я хочу понять последствия вызова pthread_createкогда std::lock_guard все еще находится в области видимости.

Это безопасно?Будет ли блокировка применяться к новому потоку (я не собираюсь так)?

void log (std::string message)
{
    std::lock_guard<std::mutex> lck(mtx);

    _outputFile << message << std::endl;
    _outputFile.flush();
    _sequence_number++;
    _curr_file_size = _outputFile.tellp();

    if (_curr_file_size >= max_size) {
        char *lf = strdup(_logfile.c_str());
        // Create an independent thread to compress the file since
        // it takes some time to compress huge files.
        if (!_compress_thread) {
            pthread_create(&_compress_thread, NULL, compress_log, (void *)lf);
        }
    }
}

void * compress_log (void *arg) 
{
    pthread_detach(pthread_self());

    // Code to compress the file
    // ...

   { // Create a scope for lock_gaurd

       std::lock_guard<std::mutex> lck(mtx);
       _compress_thread = NULL;
   }
   pthread_exit(NULL);
}

1 Ответ

0 голосов
/ 15 февраля 2019

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

  1. Мьютекс разблокирован - он блокируется и выполнение потока продолжается.
  2. Мьютекс уже заблокирован - поток выполняетне продолжить, но ждет, пока мьютекс не будет разблокирован.

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


Не связанный совет: используйте std::thread вместо pthread_create таким образом ваше приложение становится более переносимым:

    std::thread{ [lf] { compress_log(lf); } }.detach();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...