готов лаби 4 курс 1 сим / СПЗ / laba_7
.docxМіністерство освіти і науки, молоді та спорту України
Кіровоградський національний технічний університет
МТФ
Кафедра Програмного забезпечення
Дисципліна СПЗ
Лабораторна робота №7
Виконав ст. гр. КІ-09-2
Жабчик Є.Л.
Перевірив викладач
Бісюк В.А.
Кіровоград 2012
Завдання:
Скласти програму, в якій запустити 2 процеси з 2-ма потоками в кожному, в кожному процесі задати 2 масиви по 100 цілих чисел і заповнити їх довільними числами. Відкрити в одному потоці 2 текстових файли, ініціалізувати семафор, виконати запис елементів масивів в файли за наступним алгоритмом. Потоки 1/1 (№ процесу/№ потоку) та 1/2 захоплюють і блокують семафор заносять по 25 перших елементів своїх масивів в файл 1, а 25 наступних в файл 2, потім розблоковують семафор, потік 2/1 та 2/2 захоплюють семафор і виконують те саме. Повторити операцію поки всі елементи масивів не будуть передані в файл.
Лістинг
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <process.h>
#include <time.h>
///--------------------------------------------------------------------------//
HANDLE hConsole;
HANDLE hSemaphore = NULL;
int ProcNum=1;
///--------------------------------------------------------------------------//
unsigned __stdcall FirstStr(void *arg)
{
DWORD dwWaitResult = 1;
int mas1[25];
for(int i=0; i!=25; i++)
{
mas1[i]=i;
}
int mas2[100];
for(int i=0; i!=25; i++)
{
mas2[i]=i;
}
while(dwWaitResult != WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject( hSemaphore, 50 );
}
Sleep(rand() % 500);
if (ReleaseSemaphore(hSemaphore, 1, NULL) == TRUE)
{
if(ProcNum==1)
{
std::ofstream out("1-1.txt");
out << "process 1 thread 1\n";
for(int i=0; i!=25; i++)
{
out << mas1[i];
}
out << "\n";
for(int i=0; i!=25; i++)
{
out << mas2[i];
}
std::cout << "process " << ProcNum << ", thread 1 wrote to file..." << std::endl;
out.close();
Sleep(rand() % 500);
}
else
{
std::ofstream out("2-1.txt");
out << "process 2 thread 1\n";
for(int i=0; i!=25; i++)
{
out << mas1[i];
}
out << "\n";
for(int i=0; i!=25; i++)
{
out << mas2[i];
}
std::cout << "process " << ProcNum << ", thread 1 wrote to file..." << std::endl;
out.close();
Sleep(rand() % 500);
}
}
else
std::cout << "process " << ProcNum << ", thread 1 failed to write..." << std::endl;
_endthread();
return EXIT_SUCCESS;
}
///--------------------------------------------------------------------------//
unsigned __stdcall SecondStr(void *arg) //аналогична первой
{
DWORD dwWaitResult = 1;
int mas1[25];
for(int i=0; i!=25; i++)
{
mas1[i]=i;
}
int mas2[100];
for(int i=0; i!=25; i++)
{
mas2[i]=i;
}
while(dwWaitResult != WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject( hSemaphore, 50 );
}
Sleep(rand() % 500);
if (ReleaseSemaphore(hSemaphore, 1, NULL) == TRUE)
{
if(ProcNum==1)
{
std::ofstream out("2-1.txt");
out << "process 1 thread 1\n";
for(int i=0; i!=25; i++)
{
out << mas1[i];
}
out << "\n";
for(int i=0; i!=25; i++)
{
out << mas2[i];
}
std::cout << "process " << ProcNum << ", thread 2 wrote to file..." << std::endl;
out.close();
Sleep(rand() % 500);
}
else
{
std::ofstream out("2-2.txt");
out << "process 2 thread 1\n";
for(int i=0; i!=25; i++)
{
out << mas1[i];
}
out << "\n";
for(int i=0; i!=25; i++)
{
out << mas2[i];
}
std::cout << "process " << ProcNum << ", thread 2 wrote to file..." << std::endl;
out.close();
Sleep(rand() % 500);
}
}
else
std::cout << "process " << ProcNum << ", thread 2 failed to write..." << std::endl;
_endthread();
return EXIT_SUCCESS;
}
///--------------------------------------------------------------------------//
int main(int argc, char* argv[])
{
HANDLE hThreads[2];
unsigned threadID[5];
int n = 0;
char c;
STARTUPINFO StartInfo;
PROCESS_INFORMATION ProcInfo;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
srand ( time(NULL) );
hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, "Semaphore");
if (hSemaphore == NULL)
{
SetConsoleTextAttribute(hConsole, 2);
std::cout << "creating process 1...\n" ;
hSemaphore = CreateSemaphore(NULL, 2, 2, "Semaphore");
std::cout << "process 1 created, semaphore too!\n";
Sleep(rand() % 500);
std::cout << "creating process 2...\n" ;
Sleep(rand() % 500);
ZeroMemory(&StartInfo,sizeof(STARTUPINFO));
if (CreateProcess(argv[0],//clone process
NULL,
NULL,
NULL,
FALSE,
NULL,
NULL,
NULL,
&StartInfo,
&ProcInfo) == FALSE)
{
SetConsoleTextAttribute(hConsole, 4);
std::cout << "failed to create process 2!\n";
system("PAUSE");
return EXIT_SUCCESS;
}
}
else
{
SetConsoleTextAttribute(hConsole, 2);
std::cout << "process 2 created!\n";
ProcNum = 2;
}
SetConsoleTextAttribute(hConsole, 15);
Sleep(rand() % 500);
std::cout << "process " << ProcNum << " starting thread " << n+1 << std::endl;
hThreads[n] = (HANDLE)_beginthreadex(NULL, 0, &FirstStr, NULL, 0, &threadID[n]);
n++;
Sleep(rand() % 500);
std::cout << "process " << ProcNum << " starting thread " << n+1 << std::endl;
hThreads[n] = (HANDLE)_beginthreadex(NULL, 0, &SecondStr, NULL, 0, &threadID[n]);
n++;
WaitForMultipleObjects(n, hThreads, TRUE, INFINITE);
Sleep(rand() % 500);
std::cout << std::endl << "process " << ProcNum << " finished" << std::endl;
if (ProcNum == 1)
{
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
SetConsoleTextAttribute(hConsole, 7);
std::cout << std::endl << "semaphore closed" << std::endl;
system("PAUSE");
}
return EXIT_SUCCESS;
}