Не работает семафор в СИ под Windows. Мега-маразм!
Суть проблемы: Есть три проги. main, child1, child2. Main создает семафор(CreateSemaphore) и два процесса (child1, child2). Семафору даю название "sem1". Дети при рождении делают OpenSemaphore и пытаются открыть тот самый "sem1". Далее они выполняют некоторые операции и рано или поздно происходит WaitForSingleObject, сначало у первого, а потом без всяких ReleaseSemaphore и у второго. И они оба идут дальше. Ничего не могу понять.
Сначало у меня это было в одном исходнике (в качестве нитей), тоесть там вообще один семафор на всю программу без всяких OpenSemaphore и не работало всё равно!
PS: если надо я могу кусок кода выложить даже.
A child process created by the CreateProcess function can inherit a handle to a semaphore object if the lpSemaphoreAttributes parameter of CreateSemaphore enabled inheritance.
A process can specify the semaphore-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.
A process can specify the name of a semaphore object in a call to the OpenSemaphore or CreateSemaphore function.
То есть Вы делаете не совсем так, как надо. Семафор в создаваемые ПРОЦЕССЫ (не потоки) нужно передавать не по имени а по HANDLE при помощи функции DuplicateHandle. И все это передается через функцию CreateProcess.
В разных процессах по имени можно пользовать объекты типа Mutex.
Вообщем вот эти функции прямо как они есть в проге:
в главной
CreateMutex(NULL, TRUE, "sem1");
СreateProcess(NULL,"project1.exe",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
в детях
OpenMutex(MUTEX_ALL_ACCESS, FALSE, "sem1");
WaitForSingleObject(sem, INFINITE);
Вот так вообще не работает, тоесть процессы стартуют, и как только доходят до WaitForSingleObject(sem, INFINITE); то всё конец, начинают чего-то ожидать.
А если поменять TRUE на FALSE вот здесь: СreateProcess(NULL,"project1.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
Это кажется параметр наследования. То они на строку WaitForSingleObject(sem, INFINITE); реагировать не будут, как будто семафоры разные.
Сейчас попробовал через Mutex сделать, но все равно фигня, абсолютно тоже самое.
Вообщем вот эти функции прямо как они есть в проге:
в главной
CreateMutex(NULL, TRUE, "sem1");
СreateProcess(NULL,"project1.exe",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
в детях
OpenMutex(MUTEX_ALL_ACCESS, FALSE, "sem1");
WaitForSingleObject(sem, INFINITE);
Вот так вообще не работает, тоесть процессы стартуют, и как только доходят до WaitForSingleObject(sem, INFINITE); то всё конец, начинают чего-то ожидать.
Так еще бы они не ожидали, при создании мьютекса выставлено true, значит он создается захваченным создающим процессом, и все кто ждут, будут ждать, пока он не сделает ReleaseMutex.
А если поменять TRUE на FALSE вот здесь: СreateProcess(NULL,"project1.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
Это кажется параметр наследования. То они на строку WaitForSingleObject(sem, INFINITE); реагировать не будут, как будто семафоры разные.
Так еще бы они не ожидали, при создании мьютекса выставлено true, значит он создается захваченным создающим процессом, и все кто ждут, будут ждать, пока он не сделает ReleaseMutex.
Так это понятно! Как сделать чтобы один процесс захватывал мьютекс, а второй захватывал его же и ждал, пока тот освободится (как и должно быть).
Блиин...прогу не могу сдать, только из-за этого глюка. Нужно ваще срочно, начало следующей недели - срок!
S_T: Тоесть это как? Если мы например мьютекс используем, как c ним?
Так это понятно! Как сделать чтобы один процесс захватывал мьютекс, а второй захватывал его же и ждал, пока тот освободится (как и должно быть).
Блиин...прогу не могу сдать, только из-за этого глюка. Нужно ваще срочно, начало следующей недели - срок!
А поподробней, как ты делаешь, нельзя? Если оба процесса ждут мьютекса, то при освобождении создателем, (он ведь захваченный) один из них хватает, а другой ждет.(так должно быть)
HANDLE hMyMutex;
Создаешь mutex
hMutex = CreateMutex( NULL, FALSE, "MyMutexName");
Mutex свободен
Запускаешь процессы,
Где-нибудь захватываешь Mutex
DWORD dwWaitResult = WaitForSingleObject( hMyMutex, dwMilliseconds );
потом обязательно в этом же процессе освобождаешь
if (!ReleaseMutex(hMyMutex) )
{
}
hMyMutex можешь передавать процессам как параметр
а можно в каждом процессе выполнить
hMutex = CreateMutex( NULL, FALSE, "MyMutexName");
Имя дб ОБЯЗАТЕЛЬНО одно и то же
Mutex будет создан только 1 раз и все процессы работают с одним и тем же Mutex`ом
hMyMutex можешь передавать процессам как параметр
а можно в каждом процессе выполнить
hMutex = CreateMutex( NULL, FALSE, "MyMutexName");
Не CreateMutex, а OpenMutex.
Не CreateMutex, а OpenMutex.
CreateMutex IMHO лучше чем OpenMutex, тк программа становится более независима от последовательности запуска процессов: кто первый сработал - тот и создал мьютекс
Как получилось: отключал по одному процессу и корректировал координаты отрисовки. ВСЁ! Никаких операций с мьютексами не производил. Даже переменные связанные с ними не трогал. Потом пустил два процесса сразу. И всё заработало!