// Функция 1-го потока - получаем и выводим число
// записанных в файл символов
static unsigned __stdcall funThread1(void *arg){
int iDelay = 5000;
DWORD dwM = dwWROperationsMaxNumber;
//цикл потока
while(dwM--){
//cs-in
if(SYCHRONIZATION_STATUS) EnterCriticalSection(&cs);
hFile = CreateFile(SHARE_FILE_NAME, GENERIC_READ, 0,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE){
Form1->Memo1->Lines->Add((AnsiString)GetFileSize(hFile, NULL));
}
else{
Form1->Memo1->Lines->Add(ERROR_OPENING_FILE);
}
CloseHandle((HANDLE)hFile);
hFile=0;
//cs-out
if(SYCHRONIZATION_STATUS) LeaveCriticalSection(&cs);
delay(iDelay);
}
return 0;
}
//-----------------------------------------
// Функция 2-го потока - запись в файл
static unsigned __stdcall funThread2(void *arg){
delay(1000);
int iDelay = 5000;
DWORD
dwM = dwWROperationsMaxNumber,
dwPos,
iBufSize = 10/*sizeof(STRING_TO_WRITE.c_str())*/,
dwBytesWritten;
//цикл потока
while(dwM--){
//cs-in
if(SYCHRONIZATION_STATUS) EnterCriticalSection(&cs);
hFile = CreateFile(SHARE_FILE_NAME, GENERIC_WRITE, 0,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE){
dwPos = SetFilePointer(hFile, 0, NULL, FILE_END);
WriteFile(hFile, STRING_TO_WRITE.c_str(),
iBufSize, &dwBytesWritten, NULL);
dwTotalSymbolsWritten += /*dwBytesWritten*/iBufSize;
Form1->Memo2->Lines->Add((AnsiString)dwTotalSymbolsWritten);
}
else{
Form1->Memo2->Lines->Add(ERROR_OPENING_FILE);
}
CloseHandle((HANDLE)hFile);
hFile=0;
//cs-out
if(SYCHRONIZATION_STATUS) LeaveCriticalSection(&cs);
delay(iDelay);
}
}
Синхронизация потоков
В процессе есть основной поток, который читает из текстового файла, и есть второй поток, который записывает данные в тот же файл. Как можно проиллюстрировать присутствие/отсутствие синхронизации потоков? Записываемые данные абсолютно произвольные, метод - критические секции.
Заставьте каждый поток ждать, к примеру, 2 секунды перед выходом. Тогда, если синхронизация работает правильно, то временной интервал между любыми изменениями вашего файла будет >= 2 секунды.
очень интересная идея. наверное, как-раз подойдет, спасибо!
Подскажите еще пожалуйста. Возник вопрос, можно ли как-нибудь получать новый размер файла, если дескриптор в течение времени не закрывается? т.е ОС не знает новый размер файла, пока он не закроется, и, соответственно, GetFileSize(...) возвращает одно и то же значение при каждом запуске.
При правильном открытии файла GetFileSize() возвращает правильное значение при каждом новом вызове.
Код:
здесь 2 потока, один записывает в файл строку через интервал времени, другой - выводит размер файла.
Проблема в том, что попытки создать дескриптор файла неуспешны - в обоих случаях, как при записи, так и при попытке получения размера - CreateFile возвращает INVALID_HANDLE_VALUE.
Вторая проблема - программа завершается с ошибкой при включении синхронизации - т.е. когда флаг SYCHRONIZATION_STATUS = true. Но ведь именно обозначенная секция имхо является критической, т.к. там операции с файлом.
Помогите разобраться, что я сделал не так, я сам уже напрочь запутался((
Дополню: проблема с дескриптором появляется после первого использования файла и его закрытия (в любом из потоков). Создаваемые далее дескрипторы имеют значение INVALID_HANDLE_VALUE.
1. Вы инициализируете критическую секцию перед ее использованием?
2. CreateFile с флагом CREATE_NEW возвращает INVALID_HANDLE_VALUE, если такой файл уже существует. Вы удаляете файл после каждого вызова?
все, разобрался) спасибо! заменил CREATE_NEW на OPEN_EXISTING
в одном потоке пикнуть: Beep(880,200);
Sleep(200);
в другом пикнуть Beep(920,200);
Sleep(200);
Очень удобно и глаза не напрягаются!