Народ, помогите плиз, только начал изучать синхронизацию потоков, а именно: критические секции. Чтоб все освоить на практике, пытаюсь сделать след. программку: имеется общий ресурс: переменная типа FILE, также имеется 2 потка: первый - создает файл и записывает туда числа от 0 до 4, второй - редактирует этот файл и пишет числа от 0 до 9. Проблема собственно с критическими секциями. Сначала у меня было без использования критических секций, но потоки работали некорректно, т.е в файл писался мусор, тогда я добавил Sleep(20) во второй поток, и все стало нормально, но вообще то так же не делается, и вот когда я дошел до изучения критических секций, то подумал, что раз такое существует, то каждый процесс надо туда затолкать и тогда процессы выполнятся корректно, но у меня возникли проблемы, что не так делаю, подскажите: Код (Text): DWORD WINAPI WriteMyFile_1(); DWORD WINAPI WriteMyFile_2(); //общий ресурс FILE *F; //Объявление структуры критичесокй секции CRITICAL_SECTION cs_file; int main() { //Создаем первый поток, который запишет в файл HANDLE hWriteThread = BeginThreadEx(NULL,NULL, &WriteMyFile_1, NULL,NULL,NULL); CloseHandle(hWriteThread); //Создаем второй поток, который запишет в файл HANDLE hReadThread = BeginThreadEx(NULL,NULL, &WriteMyFile_2, NULL,NULL,NULL); CloseHandle(hReadThread); } DWORD WINAPI WriteMyFile_1() { //Иницаализация элементов структуры CRITICAL_SECTION InitializeCriticalSection(&cs_file); //Открываем критическую секцию EnterCriticalSection(&cs_file); F = fopen("MyFileTest.txt", "w"); //проверка if(F == NULL) { MessageBox(hDlg1,"Файл не был создан","Error",MB_ICONHAND|MB_OK); } TCHAR bufThread_1[]="Начало выполнения первого потока"; fprintf(F,"%s\n", bufThread_1); //Записываем начало исполнения первого потока for (int one=0; one<5; one++) { fprintf(F,"%d\n", one); //и записывать в файл значения от 0 до 5 } fclose(F); //Закрываем критическую секцию LeaveCriticalSection(&cs_file); return 0; } DWORD WINAPI WriteMyFile_2() { //Иницаализация элементов структуры CRITICAL_SECTION InitializeCriticalSection(&cs_file); //Открываем критическую секцию EnterCriticalSection(&cs_file); F = fopen("MyFileTest.txt", "a"); //проверка if(F == NULL) { MessageBox(hDlg1,"Файл не был создан","Error",MB_ICONHAND|MB_OK); } TCHAR bufThread_2[]="Начало выполнения второго потока"; fprintf(F,"%s\n", bufThread_2); //Записываем начало исполнения второго потока for (int one=0; one<10; one++) { fprintf(F,"%d\n", one); //и записывать в файл значения от 0 до 10 } fclose(F); //Закрываем критическую секцию LeaveCriticalSection(&cs_file); return 0; }
Отредактировал исходник, добавл InitializeCriticalSection, но все равно не совсем так: все равно запись идет некорректно, т.е сначала все нормально, когда первый раз, то пишется как надо: Код (Text): Начало выполнения первого потока 0 1 2 3 4 Начало выполнения второго потока 0 1 2 3 4 5 6 7 8 9 Т.е. и 1 и 2 поток все записывают, но бывает, что записываетя и так: Код (Text): Начало выполнения первого потока 0 1 2 3 4 5 6 7 8 9 Т.е. первая фраза из 1-го потока, а остальное из 2, как может такое происходить, если критические секции и предназначены для того чтобы ограничить доступ 2 потока пока выполняется 1, т.е получается так что первый вытесняется системой, а тут подошло время второго и он сразу же записывает, что по идее то не должен делать, система же должна запомнить то место на котором закончил свое выполнение первый поток, потом опять выделить ему время, а потом уже только второму... я так понимаю. Конечно можно было бы решить это с помощью приоритета потоков, но мне же важно разобраться именно в крит. секциях, как сделать задуманное, не приостанавливая второй поток вызовом Sleep, и не повышая приореты потоков? Объясните пож-та, ну ни как не вкуриваю чё то.. =( И в добавку: если я вызвал InitializeCriticalSection, то надо и удалить эл-ты этой структуры вызовом DeleteCriticalSection, только где ее вызвать?
Benzin Код в студию. И ещё если ты создаёшь первым поток WriteMyFile_1, это не значит, что он первым займёт критическую секцию. + Рихтера почитай.