Mutex не работает с двумя запущенными процессами - PullRequest
0 голосов
/ 07 февраля 2012

Я программирую на C, используя win32 api.
Моя программа запускается с void main, я делаю некоторые действия, которые создают мьютекс с определенным именем, а затем запускают на нем функцию waitForSingleObject с параметром времени INFINITE.

Затем я запускаю процесс EXE с помощью функции createProcess.
Процесс EXE имеет похожий код, который теперь выполняет createMutex с тем же именем, которое я делал ранее с родительским процессом.

Как я понимаю, я должен получить дескриптор того же мьютекса, который я создал в родительской программе ... потому что он имеет то же имя.Таким образом, после этого код EXE снова выполняет WaitForSingleObject для дескриптора мьютекса с теми же параметрами.

Я ожидал, что это остановится и будет ждать, но это продолжалось, так как это было каким-то образом сигнализировано, но на этом этапе я нигде не делал сигнал.
Я пытался заменить параметр INFINITE на 0и посмотреть, получу ли я WAIT_TIMEOUT, но это тоже не сработало.
Почему мой мьютекс не работает?

Спасибо

добавлен соответствующий код: (Я пытался поместить только те вещи, которые имеют отношение к делу) * обратите внимание, что EXE-файл Process1 содержит код, который выполняет openfileInDirectory с тем же именем файла, что и вvoid main и для записи.** Мой мьютекс, которому нужно следовать, называется writeMutex.FileSystemMutex - это еще один файл, который не имеет ничего общего с моей текущей проблемой.

// Global variables definition from library header
void* viewVec;
HANDLE fileHandle;
int directoryLastBlockIndex;
FilesInProcessUse processFiles;          
HANDLE fileSystemMutex;
HANDLE filesAccessSemaphore;

void main()
{         

    FileDescriptor* fd, *fd2;
    int message,message2,message3;
    int processId = GetCurrentProcessId();
    char* input= NULL;

    /* print out our process ID */
    printf("Process %d reporting for duty\n",processId);


    fileSystemMutex = CreateMutex(NULL,FALSE,FILE_SYSTEM_MUTEX_NAME);
    printf("Process %d: After creating fileSystem mutex\n",processId);
    filesAccessSemaphore = CreateSemaphore(NULL,MAX_ACCESSORS_FOR_ALL_FILES,MAX_ACCESSORS_FOR_ALL_FILES,FILE_SYSTEM_SEMAPHORE_NAME);
    printf("Process %d: After creating filesAccessSemaphore\n",processId);

    initfs("C",NUM_OF_BLOCKS_IN_DISK,NUM_OF_BLOCKS_IN_DISK);

    viewVec = attachfs("C"); // Saving the address of the vector in global pointer.  

    if(viewVec!=NULL)
    {
        printf("Process %d: After AttachFS which succeded\n",processId);
        fd = (FileDescriptor*) createFileInDirectory("FileX",2,&message);
        if (fd!=NULL)
        {
            printf("Process %d:successfuly created the file: FileX in Drive C\n",processId);
        }
        else
        {
            printErrMessage(message);
        }
    }
    else
    {
        printf("Process %d: After AttachFS, which failed\n",processId);
    }

    fd = (FileDescriptor*) openFileInDirectory("FileX",READ_PERMISSION,&message);
    if(fd!=NULL)
    {
        printf("Process %d: opened FileXfile for read succefully",processId);
    }
    else
    {
        printf("Process %d:",processId);
        printErrMessage(message);
    }
    closeFileInDirectory(fd);
    fd = (FileDescriptor*) openFileInDirectory("FileX",WRITE_PERMISSION,&message);
    if(fd!=NULL)
    {
        printf("Process %d: opened FileXfile for write succefully",processId);
    }
    else
    {
        printf("Process %d:",processId);
        printErrMessage(message);
    }

    fd2 = (FileDescriptor*) openFileInDirectory("FileX",WRITE_PERMISSION,&message);
    if(fd!=NULL)
    {
        printf("Process %d: opened FileX file for write succefully",processId);
    }
    else
    {
        printf("Process %d:",processId);
        printErrMessage(message);
    }
}
}


void* openFileInDirectory(char* fileName, int ReadWriteFlag, int* out_ErrMessage)
{

    SystemInfoSection* sysInfo = readSystemInformationFromBeginingOfVector((char*)viewVec);
    DirectoryEntry* fileEntryInDirOffset;
    FileDescriptor* openfileDescriptor = NULL;
    int fileIndexInOpenFiles = 0;
    int writeRV;

    //Mark that another file is being processed 
    WaitForSingleObject(filesAccessSemaphore,INFINITE);


    //Check if the file exists else return error
    if(isFileAlreadyExisting(fileName, sysInfo->directoryStartBlockIndex, &fileEntryInDirOffset))
    {
        fileIndexInOpenFiles = getFileIndexInOpenFileDirectory(fileName);
        processFiles.allFilesVector[fileIndexInOpenFiles].accessSemaphore = CreateSemaphore(NULL,MAX_FILE_ACCESSORS,MAX_FILE_ACCESSORS,fileName);
        WaitForSingleObject(processFiles.allFilesVector[fileIndexInOpenFiles].accessSemaphore,INFINITE);
        if (ReadWriteFlag == WRITE_PERMISSION)
        {
            char writeMutexName[15];
            strcpy(writeMutexName, WRITE_MUTEX_PREFIX);
            strcat(writeMutexName, fileName);
            processFiles.allFilesVector[fileIndexInOpenFiles].writeMutex = CreateMutex(NULL,FALSE,writeMutexName);

            WaitForSingleObject(processFiles.allFilesVector[fileIndexInOpenFiles].writeMutex,INFINITE);

            //writeRV = WaitForSingleObject(processFiles.allFilesVector[fileIndexInOpenFiles].writeMutex,MAX_WAIT_TIMEOUT_IN_FS);
            //if(writeRV == WAIT_TIMEOUT)
            //{
            //  ReleaseSemaphore(processFiles.allFilesVector[fileIndexInOpenFiles].accessSemaphore,1,NULL);
            //  //return error indicating that another process is already writing to the file AND RETURN FROM THE FUNCTION
            //  *out_ErrMessage = ERR_FILE_IS_ALREADY_OPEN_TO_A_WRITE_BY_SOME_PROCESS;
            //  return openfileDescriptor;

            //}
        }

        processFiles.FDInProcessUseVector[fileIndexInOpenFiles].fileDirectoryEntry = fileEntryInDirOffset;
        processFiles.FDInProcessUseVector[fileIndexInOpenFiles].readWriteFlag = ReadWriteFlag;
        openfileDescriptor = &(processFiles.FDInProcessUseVector[fileIndexInOpenFiles]);
        processFiles.numOfFilesInUse++;


    }

    else
    {
        openfileDescriptor = NULL;
        *out_ErrMessage = ERR_FILE_NOT_FOUND;
    }
    free(sysInfo);

    return openfileDescriptor;
}

1 Ответ

4 голосов
/ 07 февраля 2012

Вы можете использовать функцию CreateMutex для создания именованного глобального мьютекса.

Логика использования глобального мьютекса обычно следующая:

  1. Вы пытаетесь создать мьютекс с помощьюиспользуя CreateMutex .Обратите внимание, что "Если мьютекс является именованным мьютексом и объект существовал до этого вызова функции, возвращаемое значение является дескриптором существующего объекта" .
  2. Вы блокируете (получаете право собственности) с помощьюиспользуя функцию WaitForSingleObject
  3. Вы разблокируете (освобождаете владельца) с помощью функции ReleaseMutex
  4. You CloseHandle возвращается Функция CreateMutex .

Вот хороший пример на C: Использование объектов Mutex

В вашем коде есть несколько проблем:

  1. Вы не освобождаете владельца от writeMutex, что, вероятно, является основной причиной, по которой этот код не может работать.
  2. Вы не проверяете возвращаемое значение одного вызова.Единственное возвращаемое значение, которое вы проверяете, это значение, возвращаемое вашей функцией.Проверьте документацию по этим функциям, чтобы можно было правильно обрабатывать возможные состояния ошибок.
  3. Вы не CloseHandle , возвращаемые функцией CreateMutex .Ни дескриптор fileSystemMutex, ни дескриптор writeMutex.
  4. Вы создаете fileSystemMutex, но тогда вы никогда его не используете.У этого мьютекса нет никакого смысла.
...