Member 13426014 Ответов: 1

Чтение двух файлов-синхронизация вперед и назад


Я пишу программу, которая создает два потока. Каждый поток отвечает за чтение одного текстового файла с одним символом в каждой строке.

Первый форматируется следующим образом:

х
0
х
0
...

Второй форматируется следующим образом:

0
я
0
я
0
я

Иногда может быть несколько букв друг за другом или несколько нулей друг за другом. Однако одна уверенность заключается в том, что если в одной строке одного файла есть буква, то соответствующая строка второго файла будет иметь 0, и наоборот.

Предполагается, что потоки будут продолжать считывать входные данные файла в глобальный массив символов до тех пор, пока не достигнут нуля. В этот момент они позволяют другому потоку взять верх. И они продолжают двигаться вперед и назад, пока оба файла не будут полностью прочитаны.

В этот момент, когда я бегу, я получаю вариации либо (1) много h, за которыми следует много i, либо (2) (Правильный ответ) непрерывный поток hihihi, либо (3) иногда много i, за которыми следует много h. Итак, я знаю, что мои методы синхронизации отключены.

Вот пример одного из моих потоков: (обратите внимание, что оба потока абсолютно одинаковы, за исключением открываемого файла.)

void *getMessage1()
{
FILE *studentOne = fopen("Student1", "r");

size_t howManyChars;
char *placeHolderChars; 
int count = 1;
while (count < 501)
{
    placeHolderChars = NULL;
    getline(&placeHolderChars, &howManyChars, studentOne);

    if(strcmp(placeHolderChars, "0\n") == 0) //if we've reached a zero
    {

         pthread_mutex_unlock(&lock); 
    }
    else
    {   while(1)
        {
            if(pthread_mutex_trylock(&lock) == 0)
            {

                break;
            }
        }

        if(strlen(placeHolderChars)>0)
        {
             placeHolderChars[1] = '\0';
        }

        strcat(message,placeHolderChars);
    }

    free(placeHolderChars);

    if(feof(studentOne))
    {

        pthread_mutex_unlock(&lock); //unlock
        fclose(studentOne);
        break;
    }
    count++;

 }

return 0;
}


Вот мой основной метод:

int main(void)
{
pthread_t id1;
pthread_t id2;

pthread_create((&id1), NULL, getMessage1, NULL);
pthread_create((&id2), NULL, getMessage2, NULL);

pthread_join(id1, NULL);
pthread_join(id2, NULL);

int j;

for (j = 0; j < 1001; j++) 
{
     printf ("%c ",message[j]);
}

return 0;
}


Что я уже пробовал:

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

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

1 Ответов

Рейтинг:
1

Patrice T

Первое, что нужно сделать, это использовать отладчик и убедиться, что все идет так, как ожидалось. Проверяйте переменные по мере их изменения. Проверяйте все до тех пор, пока в качестве объяснения проблемы не останется только мьютекс.

Существует инструмент, который позволяет вам видеть, что делает ваш код, его имя отладчик Это также отличный инструмент обучения, потому что он показывает вам реальность, и вы можете увидеть, какие ожидания соответствуют реальности.
Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик-Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]
Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.