Я искал именованный мьютекс, чтобы я мог обеспечить взаимное исключение на время жизни процесса (следя за тем, чтобы только один процесс выполнялся на некоторый набор свойств). Я не нашел его (похоже, я не выглядел достаточно жестко), и поэтому я реализовал свой собственный псевдоним с именем mutex в linux, используя абстрактный сокет домена UNIX. Только одна привязка () к этому сокету будет успешной. Другая приятная вещь заключается в том, что ОС очистит абстрактный сокет домена UNIX, если процесс умрет и, следовательно, не очистит сам сокет. К сожалению, я не уверен, что вы сможете «подождать», пока этот псевдо-мьютекс станет доступным.
Абстрактный сокет домена UNIX - это сокет домена UNIX, имя которого начинается с нулевого байта. Осторожно, хотя, я считаю, что весь буфер используется в качестве имени, и поэтому вы хотите убедиться, что вы не просто memcpy или strcpy частичную строку в него, или если вы действительно убедитесь, что вы сначала заполняете весь буфер с некоторым символом .
Все, кроме первого bind () завершатся с ошибкой EADDRINUSE.
// Create an abstract socket to use as a mutex.
int err;
int mutex_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (mutex_sock == -1)
{
err = errno;
printf("main, failed creating mutex socket: %s\n",
get_error_string(errno, error_string, sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed creating mutex socket: "
"%s", get_error_string(errno, error_string,
sizeof(error_string)));
errno = err;
goto done;
}
// Bind to abstract socket. We use this as a sort of named mutex.
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path + 1, socket_name, sizeof(addr.sun_path) - 2);
result = bind(mutex_sock, (struct sockaddr*) &addr, sizeof(addr));
if (result == -1)
{
err = errno;
if (errno == EADDRINUSE)
{
printf("main, failed bind to mutex socket: %s. "
"Another instance must be running.\n",
get_error_string(errno,
error_string, sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: "
"%s. "
"Another instance must be running.",
get_error_string(errno,
error_string, sizeof(error_string)));
}
else
{
printf("main, failed bind to mutex socket: %s\n",
get_error_string(errno, error_string,
sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: %s",
get_error_string(errno, error_string,
sizeof(error_string)));
}
errno = err;
goto done;
}
Спасибо,
Ник