Объясните, пожалуйста:
std::mutex test;
if (test.try_lock( ) == true)
std::cout << "блокировка установлена" << std::endl;
else
std::cout << "блокировка не установлена" << std::endl;
test.unlock( ); // теперь разблокируем мьютекс
test.lock( ); // заблокируем его снова
if ( test.try_lock( ) ) //true можно опустить
std::cout << "блокировка установлена" << std::endl;
else
std::cout << "блокировка не установлена" << std::endl;
test.lock( ); // и последнее (заблокируем)
Ещё один вопрос. Можно ли создать с помощью этих средств программу, которая не допускает создания копии самой же себя. Я и так, и сяк пробовал, но не получается.
программа завершается аварийно?
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Нормально отрабатывает, не падает. Да и с чего бы ей падать? Смотрите в отладчике, прогоняйте через valgrind, может где-то что-то в окружающем коде влияет.
Можно ли создать с помощью этих средств программу, которая не допускает создания копии приложения
Нельзя. Ваша программа должна искать уже запущеный экземпляр себя же, и предпринимать какие-то действия в зависимости от результата. Как именно искать - зависит от многих причин, например, от целевой ОС, от ваших задач и т.д.
Из общих механизмов: первый экземпляр программы может создать и залочить какой-то специальный файл. Если при запуске програма не находит этот файл, или не может захватить его, считаем что один экземпляр уже запущен.
Если бы Вы указали откуда взяли пример, было бы проще дать верный ответ.
Проблема в том, что вызов lock для std::mutex в том же потоке нарушает предусловие вызова, если мютекс уже был захвачен:
Requires: If m is of type std::mutex, std::timed_mutex, or std::shared_timed_mutex, the calling thread does not own the mutex.
Может возникнуть ошибка:
— device_or_resource_busy — if the mutex is already locked and blocking is not possible.
И еще:
[Note: A program may deadlock if the thread that owns a mutex object calls lock() on that object. If the implementation can detect the deadlock, a resource_deadlock_would_occur error condition may be observed. —endnote]
Это и приводит к аварийному завершению или бесконечной блокировке программы.
Предотвращение запуска второй копии программы обеспечивается созданием и получения эксклюзивного доступа к какому-либо ресурсу, который должен быть виден (для проверки наличия блокировки) из разных процессов. В Windows для этого можно использовать именованные мютексы.
Решить подобную задачу std мютексами не представляется возможным, т.к. требуется синхронизация между процессами, в то время как обеспечивается только между потоками.
В Linux решить вашу задачу (запуск одной копии приложения) можно сделав блокировку собственного исполнимого файла (к счастью, его всегда легко найти в оглавлении /proc/), неблокирующим вызовом flock.
Вот пример кода
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#include <limits.h>
int
main (int ac, char *av[])
{
char expath[PATH_MAX];
ssize_t l = readlink("/proc/self/exe", expath, sizeof(expath) - 1);
if (l > 0) {
expath[l] = 0;
int fd = open(expath, O_RDONLY | O_CLOEXEC);
// printf("open %d %m\n", fd);
if (flock(fd, LOCK_EX | LOCK_NB))
perror("flock"), exit(1);
} else
perror("readlink"), exit(1);
puts("Enter>");
getchar();
}
Что непонятно, спрашивайте.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей