Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / interprocess locking

interprocess locking

fsmokeПостоялецwww16 мая 201812:57#0
Есть задача межпроцессного взаимодействия. Причем софт должен быть пипец каким кроссплатформенным. Это как минимум винда, линь,  мак, андройд(я думаю там тоже, что и в линухе будет - хотя хз - я в андрюше нуб). Заюзал буст интерпроцесс с его шаредмемори. Проблема в том, что все шаред объекты синхронизации остаются залочеными если один из процессов падает.

Чекать пид тоже не вариант - т.к. в одном процессе может быть несколько серваков и если жестко убить поток с одним серваком - свои объекты синхронизации он не разлочит/не убъет и все его клиенты останутся висеть и думать, что всё ок - ведь пид то живой.

Чекать тред ид не вариант - т.к. идшники могут повторятся. Хендлы не повторяются - но это некроссплатформенно

Хз че делать - какие у кого мысли ....

ЗЫ
Ну даже забыть про проблему нескольких серваков в процессе:

1)буст процесс - вроде как не умеет ждать сторонний процесс - только дочерний .... т.е. опять писать свой кроссплатформенный велосипед придется.

2)Смотрел на древнючий механизм блокировки файлов - не нашел кроссплатформенной реализации - опять писать кроссплатформенную обертку.... может кто видел какие нибудь готовые решения - или я буст недосмотрел?

DelfigamerПостоялецwww16 мая 201813:11#1
Первый пришедший в голову вариант - сделать по мотивам watchdog-таймеров. Тред берёт лок на определённое время, при необходимости продлевает резервацию или освобождает досрочно. Если время прошло, а явного освобождения не было - считаем, что тред упал, и локаем по-новой.
А какие у тебя есть примитивы синхронизации? Семафоры? Мьютексы? Или можно даже напрямую атомики в общей памяти гонять?

Правка: 16 мая 2018 13:12

skalogryzУчастникwww16 мая 201815:13#2
В Винде (именнованные для ipc) Мьютексы как раз разруливают эту ситуацию.
Если поток, залочивший мьютекс был прибит, то Мьютекс переходит в статус "Abandoned" (брошенка)
Следующий поток получивший лок на этот мьютекс, о таком статусе оповещается.

Критические секции, наоборот, при терминированиии потока остаются залоченными. (по-этому терминировать потоки и нельзя)

Но это всё в Винде, как в других системах - нужно смотреть. 

Правка: 16 мая 2018 15:15

DelfigamerПостоялецwww16 мая 201816:04#3
Я думаю, если это кернеловский примитив, то он должен обрабатываться вместе со стеком, TLS и прочими ресурсами на завершении.
А так - да, насильно убивать потоки категорически не рекомендуется. Настолько, что в стандартном C++ такого механизма даже не предусмотрено в принципе, можно только попросить о завершении через общую переменную и ждать, пока поток не увидит просьбу.

Ну и если прямо чешутся руки велосипедить - можно вместо этого переписать критические секции на транзакции, чтобы поток копировал состояние себе, делал операцию на своей копии, а затем атомиком ставил новую версию в оригинал, с повторной попыткой в случае, если во время обработки авторитарную версию успел поменять кто-то другой.

fsmoke
> Чекать пид тоже не вариант - т.к. в одном процессе может быть несколько
> серваков
> Чекать тред ид не вариант - т.к. идшники могут повторятся
А что, если чекать пару PID|TID?

Правка: 16 мая 2018 16:07

fsmokeПостоялецwww18 мая 201813:11#4
Короче забил я на идентификацию потока. В принципе если валится один поток - упадет всё. ладно...

Новая проблема:
заюзал boost interprocess file_lock - чтоб чекать креш сервака. всё отлично работает но есть один нюанс.... как это чудо разлочить ?

допустим создаем следящий поток

void reconnect_thrd_proc()
{
namespace bi = boost::interprocess;

bi::file_lock flock("blablafile.txt");
bi::scoped_lock<bi::file_lock> lock(flock);

//действия при падении или закрытии сервака. 
}

если сервер грохнется - всё ок.

А теперь представим, что мы хотим тихо мирно отключиться от сервера.

на деструкторе делаем что-то типа

if (_reconnect_thrd && _reconnect_thrd->joinable())
    {
      //ЗДЕСЬ НАДО РАЗЛОЧИТЬ file_lock!!!!
      _reconnect_thrd->join();
    }

Как разлочить file_lock.

Есть конечно timed_wait, но у него есть 2 недостатка:
1) хочется, чтоб поток _reconnect_thrd спал - и не жрал время проца - а здесь он будет просыпаться
2) чтоб он просыпался редко - нужно увеличить время, но тогда есть вероятность зависнуть в деструкторе на неопределенный промежуток этого времени.

Какая то простая и глупая задача. Можт я туплю......

Какие у кого мысли?

Правка: 18 мая 2018 13:12

/ Форум / Программирование игр / Общее

2001—2018 © GameDev.ru — Разработка игр