Объясните, пожалуйста:
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();
}
Что непонятно, спрашивайте.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
здравствуйте, вот решил прогнать через strace бинарник хелловорлда:
Программа-упаковщик установочного пакета должна прочитать видео-файл в CvCapture* capture = cvCreateFileCapture("videomp4");, разложить по кадрам в массив и дописать...