Using namespace std #define thinker 5
Скачать 25.02 Kb.
|
#include #include #include #include #include #include #include #include using namespace std; #define thinker 5 #define furcula 5 omp_lock_t forks[furcula]; void think(int i) { int secs = 1 + (rand() % thinker+2300); printf("Философ %d размышляет %d секунд...\n", i, secs); Sleep(secs); } void eat(int i) { int furcula_first; int furcula_second; if (i == thinker - 1) { furcula_first = 0; furcula_second = i; } else { furcula_first = i; furcula_second = i + 1; } printf("Философ %d просит вилку... у него %d вилка\n", i, furcula_first); omp_set_lock(&forks[furcula_first]); printf("Философ %d просит вилку ... у него %d вилка\n", i, furcula_second); omp_set_lock(&forks[furcula_second]); //симуляция процесса поедания пищи int secs = rand() % thinker; printf("Философ %d ест %d секунд\n...", i, secs); omp_unset_lock(&forks[furcula_second]); omp_unset_lock(&forks[furcula_first]); } void simulation(int i) { while (true) { think(i); eat(i); } } int main() { SetConsoleCP(1251); SetConsoleOutputCP(1251); int i; srand(time(NULL)); omp_set_num_threads(thinker); for (int i = 0; i < thinker; i++) { omp_init_lock(&forks[i]); // блокировка } #pragma omp parallel for private(i) for (int i = 0; i < thinker; i++) { simulation(i); } return 0; } #include #include #include #include #include #include #include #include #include #include #include using namespace std; FILE* stream; // Файловый поток. void printTimeStamp() { SYSTEMTIME timeStamp; // Текущее время. GetLocalTime(&timeStamp); // Определить текущее время. printf("%02d:%02d:%02d.%03d", // Вывести текущее время на экран. timeStamp.wHour, timeStamp.wMinute, timeStamp.wSecond, timeStamp.wMilliseconds); fprintf(stream, "%02d:%02d:%02d.%03d", // Записать текущее время в файл. timeStamp.wHour, timeStamp.wMinute, timeStamp.wSecond, timeStamp.wMilliseconds); } void writer(int& storage, int totalWriters, int& activeReaders, omp_lock_t& writeLock, bool& readLock) { #pragma omp parallel num_threads(totalWriters) // Создать параллельные { // потоки. bool flag; // Переменная используется для того, чтобы подавить вывод повторных сообщений на экран и в файл, если писатель ожидает, пока читатели завершат работу с хранилищем. int writerN = omp_get_thread_num(); // Определить номер // потока-писателя. while (true) // Выполнять в бесконечном { // цикле. flag = false; Sleep(rand() * writerN % 15000 + 3000); #pragma omp critical // Вывести информацию на экран и в файл. { printTimeStamp(); printf(": Писатель %d перешел к хранилищу...\n", writerN); fprintf(stream, ": Писатель %d перешел к хранилищу...\n", writerN); } if (!omp_test_lock(&writeLock)) { #pragma omp critical { printf("Другой писатель перешел к хранилищу раньше. "); printf("Писатель %d ожидает.\n", writerN); fprintf(stream, "Другой писатель перешел к хранилищу раньше. "); fprintf(stream, "Писатель %d ожидает.\n", writerN); } omp_set_lock(&writeLock); // Заблокировать текущий поток. } readLock = true; // Запретить доступ к хранилищу // новым читателям. while (activeReaders != 0) { if (!flag) // Если информация ещё не выводилась, { #pragma omp critical { printf("Писатель %d ожидает, пока ", writerN); printf(" читатели закончат работу с хранилищем.\n"); fprintf(stream, "Писатель %d ожидает, пока ", writerN); fprintf(stream, " читатели закончат работу с хранилищем.\n"); } } flag = true; // Отметить факт вывода информации. Sleep(100); } #pragma omp critical { printTimeStamp(); printf(": У Писателя %d появился доступ к хранилищу.\n", writerN); fprintf(stream, ": У Писателя %d появился доступ к хранилищу.\n", writerN); } Sleep(3000); storage = rand() + writerN; #pragma omp critical { printTimeStamp(); printf(": Писатель %d сделал запись в хранилище ", writerN); printf("письмо %d и закончил работу.\n", storage); fprintf(stream, ": Писатель %d сделал запись в хранилище ", writerN); fprintf(stream, "письмо %d и закончил работу.\n", storage); } readLock = false; omp_unset_lock(&writeLock); } } } /*************************************************************************/ void reader(int& storage, int totalReaders, int& activeReaders, bool& readLock) { #pragma omp parallel num_threads(totalReaders) // Создать параллельные { // потоки. bool flag; int readerN = omp_get_thread_num(); // потока-читателя. while (true) { flag = false; Sleep(rand() * readerN % 12000 + 3000); #pragma omp critical { printTimeStamp(); printf(": Читатель %d перешел к хранилищу...\n", readerN); fprintf(stream, ": Читатель %d перешел к хранилищу...\n", readerN); } while (readLock == true) // Дождаться доступа к хранилищу. { if (!flag) { #pragma omp critical { printf("Доступ к хранилищу заблокирован. "); printf("Читатель %d ожидает.\n", readerN); fprintf(stream, "Доступ к хранилищу заблокирован. "); fprintf(stream, "Читатель %d ожидает.\n", readerN); } } flag = true; // Отметить факт вывода информации. Sleep(100); } #pragma omp critical { printTimeStamp(); printf(": У Читателя %d появился доступ к хранилищу.\n", readerN); fprintf(stream, ": У Читателя %d появился доступ к хранилищу.\n", readerN); } #pragma omp atomic activeReaders++; // Увеличить количество активных читателей. Sleep(3000); #pragma omp critical { printTimeStamp(); printf(": Читатель %d прочитал из хранилища ", readerN); printf("текст %d и закончил работу.\n", storage); fprintf(stream, ": Читатель %d прочитал из хранилища ", readerN); fprintf(stream, "текст %d и закончил работу.\n", storage); } #pragma omp atomic activeReaders--; } } } void main() { double start_time = 0.0, end_time = 0.0, s1 = 0.0, s2 = 0.0; setlocale(LC_ALL, "Russian"); srand(time(NULL)); int storage = 0; // Хранилище. int totalWriters = 0, totalReaders = 0; int activeReaders = 0; omp_lock_t writeLock; // Замок для блокировки писателей. bool readLock = false; // Переменная для блокировки читателей: // true - чтение запрещено; // false - чтение разрешено. fopen_s(&stream, "log.txt", "w"); omp_init_lock(&writeLock); // Инициализировать замок. omp_set_nested(true); printf("Ввести число писателей: "); cin >> totalWriters; printf("Ввести число читателей: "); cin >> totalReaders; #pragma omp parallel sections { #pragma omp section { writer(storage, totalWriters, activeReaders, writeLock, readLock); } #pragma omp section // Вызвать процедуру моделирования { reader(storage, totalReaders, activeReaders, readLock); } } } #include #include #include #include #include #include #include #include #include #include #include using namespace std; FILE* stream; // Файловый поток. void printTimeStamp() { SYSTEMTIME timeStamp; // Текущее время. GetLocalTime(&timeStamp); // Определить текущее время. printf("%02d:%02d:%02d.%03d", // Вывести текущее время на экран. timeStamp.wHour, timeStamp.wMinute, timeStamp.wSecond, timeStamp.wMilliseconds); fprintf(stream, "%02d:%02d:%02d.%03d", // Записать текущее время в файл. timeStamp.wHour, timeStamp.wMinute, timeStamp.wSecond, timeStamp.wMilliseconds); } void writer(int& storage, int totalWriters, int& activeReaders, omp_lock_t& writeLock, bool& readLock) { #pragma omp parallel num_threads(totalWriters) // Создать параллельные { // потоки. bool flag; // Переменная используется для того, чтобы подавить вывод повторных сообщений на экран и в файл, если писатель ожидает, пока читатели завершат работу с хранилищем. int writerN = omp_get_thread_num(); // Определить номер // потока-писателя. while (true) { flag = false; Sleep(rand() * writerN % 15000 + 3000); #pragma omp critical // Вывести информацию на экран и в файл. { printTimeStamp(); printf(": Писатель %d перешел к хранилищу...\n", writerN); fprintf(stream, ": Писатель %d перешел к хранилищу...\n", writerN); } if (!omp_test_lock(&writeLock)) //проверка состояния замка без блокировки текущего процесса { #pragma omp critical { printf("Другой писатель перешел к хранилищу раньше. "); printf("Писатель %d ожидает.\n", writerN); fprintf(stream, "Другой писатель перешел к хранилищу раньше. "); fprintf(stream, "Писатель %d ожидает.\n", writerN); } omp_set_lock(&writeLock); // Заблокировать текущий поток. } readLock = true; // Запретить доступ к хранилищу // новым читателям. while (activeReaders != 0) { if (!flag) // Если информация ещё не выводилась, { #pragma omp critical { printf("Писатель %d ожидает, пока ", writerN); printf(" читатели закончат работу с хранилищем.\n"); fprintf(stream, "Писатель %d ожидает, пока ", writerN); fprintf(stream, " читатели закончат работу с хранилищем.\n"); } } flag = true; // Отметить факт вывода информации. Sleep(100); } #pragma omp critical { printTimeStamp(); printf(": У Писателя %d появился доступ к хранилищу.\n", writerN); fprintf(stream, ": У Писателя %d появился доступ к хранилищу.\n", writerN); } Sleep(3000); storage = rand() + writerN; #pragma omp critical { printTimeStamp(); printf(": Писатель %d сделал запись в хранилище ", writerN); printf("письмо %d и закончил работу.\n", storage); fprintf(stream, ": Писатель %d сделал запись в хранилище ", writerN); fprintf(stream, "письмо %d и закончил работу.\n", storage); } readLock = false; omp_unset_lock(&writeLock); } } } /*************************************************************************/ void reader(int& storage, int totalReaders, int& activeReaders, bool& readLock) { #pragma omp parallel num_threads(totalReaders) // Создать параллельные { // потоки. bool flag; int readerN = omp_get_thread_num(); // потока-читателя. while (true) { flag = false; Sleep(rand() * readerN % 12000 + 3000); #pragma omp critical { printTimeStamp(); printf(": Читатель %d перешел к хранилищу...\n", readerN); fprintf(stream, ": Читатель %d перешел к хранилищу...\n", readerN); } while (readLock == true) // Дождаться доступа к хранилищу. { if (!flag) { #pragma omp critical { printf("Доступ к хранилищу заблокирован. "); printf("Читатель %d ожидает.\n", readerN); fprintf(stream, "Доступ к хранилищу заблокирован. "); fprintf(stream, "Читатель %d ожидает.\n", readerN); } } flag = true; // Отметить факт вывода информации. Sleep(100); } #pragma omp critical { printTimeStamp(); printf(": У Читателя %d появился доступ к хранилищу.\n", readerN); fprintf(stream, ": У Читателя %d появился доступ к хранилищу.\n", readerN); } #pragma omp atomic activeReaders++; // Увеличить количество активных читателей. Sleep(3000); #pragma omp critical { printTimeStamp(); printf(": Читатель %d прочитал из хранилища ", readerN); printf("текст %d и закончил работу.\n", storage); fprintf(stream, ": Читатель %d прочитал из хранилища ", readerN); fprintf(stream, "текст %d и закончил работу.\n", storage); } #pragma omp atomic activeReaders--; } } } void main() { setlocale(LC_ALL, "Russian"); srand(time(NULL)); int storage = 0; // Хранилище. int totalWriters = 0, totalReaders = 0; int activeReaders = 0; omp_lock_t writeLock; // Замок для блокировки писателей. bool readLock = false; // Переменная для блокировки читателей: // true - чтение запрещено; // false - чтение разрешено. fopen_s(&stream, "log.txt", "w"); omp_init_lock(&writeLock); // Инициализировать замок. omp_set_nested(true); printf("Ввести число писателей: "); cin >> totalWriters; printf("Ввести число читателей: "); cin >> totalReaders; #pragma omp parallel sections { #pragma omp section { writer(storage, totalWriters, activeReaders, writeLock, readLock); } #pragma omp section // Вызвать процедуру моделирования { reader(storage, totalReaders, activeReaders, readLock); } } } |