Проблема с вызовами perror (), влияющими на блокировку / разблокировку семафора - PullRequest
0 голосов
/ 21 июня 2011

Я пытаюсь выполнить некоторую базовую параллельную обработку, чтобы сделать нечетно-четную сортировку целых чисел, используя сегменты разделяемой памяти POSIX и безымянные семафоры. У меня почти все работает на данный момент, за исключением одного последнего момента: если я не выполняю perror () непосредственно после того, как семафор блокирует / разблокирует, код действует по-другому (и впоследствии сортируется неправильно). Если я оставлю вызовы perror () сразу после блокировки и разблокировки семафора, код прекрасно сортирует массив целых чисел.

int semaphoreCheck = sem_init(&(sharedData->swapSem), 1, 1);

if (semaphoreCheck == -1)
{
    perror( "failed to initialize semaphore" );
    exit(EXIT_FAILURE);
}

pid_t fork1;
fork1 = fork();
if (fork1 == 0)
{
    // original.child
    pid_t fork2;
    fork2 = fork();
    if (fork2 == 0)
    {
        // child.child
        // do a portion of the sort here
        while(sharedData->evenSwap || sharedData->oddSwap)
        {
            // obtain lock on the shared vector
            // int commandCheck = shmctl(sharedID, SHM_LOCK, NULL);
            int commandCheck = sem_wait(&(sharedData->swapSem));
            perror("semaphore lock");
            // if lock was obtained
            if (commandCheck == 0)
            {
                sharedData->evenSwap = false;
                for( int index = 1; index < arraySize - 1; index +=2)
                {
                    if( sharedData->vecData[index] > sharedData->vecData[index + 1] )   
                    {
                        int temp;
                        temp = sharedData->vecData[index];
                        sharedData->vecData[index] = sharedData->vecData[index+1];
                        sharedData->vecData[index+1] = temp;
                        sharedData->evenSwap = true;
                    }       
                }
                // release lock on the shared vector
                commandCheck = sem_post(&(sharedData->swapSem));
                perror("semaphore unlock");
                if (commandCheck == -1)
                {
                    perror("failed to unlock shared semaphore");
                }
            }
            else perror("failed to lock shared semaphore");
        }
        _exit(0);
    }
    else if (fork2 > 0)
    {
        // child.parent
        // do a portion of the sort here
        while(sharedData->evenSwap || sharedData->oddSwap)
        {
            // obtain lock on the shared vector
            int commandCheck = sem_wait(&(sharedData->swapSem));
            perror("semaphore lock");
            // if lock was obtained
            if (commandCheck == 0)
            {
                sharedData->oddSwap = false;
                for( int index = 0; index < arraySize - 1; index +=2)
                {
                    if( sharedData->vecData[index] > sharedData->vecData[index + 1] )   
                    {
                        int temp;
                        temp = sharedData->vecData[index];
                        sharedData->vecData[index] = sharedData->vecData[index+1];
                        sharedData->vecData[index+1] = temp;
                        sharedData->oddSwap = true;
                    }       
                }
                // release lock on the shared vector
                commandCheck = sem_post(&(sharedData->swapSem));
                perror("semaphore unlock");
                if (commandCheck == -1)
                {
                    perror("failed to unlock shared semaphore");
                }
            }
            else perror("failed to lock shared semaphore");
        }
        _exit(0);
    }
    else
    {
        // child.error
        // forking error.
        perror("failed to fork in child");
        exit(EXIT_FAILURE);
    }
}
else if( fork1 > 0)
{
    // original.parent
    // wait for the child process to finish.
    waitpid(fork1, NULL, 0);

}
else
{
    // forking error
    perror("failed to fork");
    exit(EXIT_FAILURE);
}

Я могу только догадываться, что это связано с тем, как семафор блокирует процесс, если ожидание не может быть выполнено, но я не понимаю, как вызовы perror () исправляют его.

1 Ответ

0 голосов
/ 21 июня 2011

Я думаю, что ваша проблема может быть связана с тем, как вы (не) проверяете, что условия остаются в силе после получения семафора, или что сами условия проверки неверны.

У вас есть:

    while(sharedData->evenSwap || sharedData->oddSwap)
    {
        // obtain lock on the shared vector
        int commandCheck = sem_wait(&(sharedData->swapSem));
        perror("semaphore lock");
        // if lock was obtained
        if (commandCheck == 0)
        {
            sharedData->oddSwap = false;

После того, как вы получите семафор, вам, вероятно, следует проверить, что либо sharedData->evenSwap, либо sharedData->oddSwap все еще имеет значение true, оставив семафор, если нет.Это стандартная идиома;вы проверяете, блокируете и перепроверяете, потому что статус мог измениться между первоначальной проверкой и временем, когда вы получили блокировку.

В соответствии с этой гипотезой вызовы perror() изменяют время процессов, позволяя условиямоставаться неизменным дольше, чем при отсутствии вызовов perror().Итак, где-то есть проблема с синхронизацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...