code
Критическая секция со списками
#include <windows.h>
#include <process.h>
#include <iostream>
#include <ctime>
#include <conio.h>
#include <string>
#include <fstream>
using namespace std;
struct List
{
int item;
List *Next;
};
List *list = new List;
List *Head = NULL;
CRITICAL_SECTION critAdd, critFile, critFind;
HANDLE AddThread, FindThread;
ofstream file;
void saveFile(string str){
EnterCriticalSection(&critFile);
file.open("log.txt",ios_base::app);
file<<endl<<str;
file.close();
LeaveCriticalSection(&critFile);
}
void Add(void *)
{
srand(time(NULL));
while(true)
{
EnterCriticalSection(&critAdd);
List *temp = new List;
temp->Next = NULL;
temp->item = rand() % 100 + 0;
temp->Next = Head;
Head = temp;
LeaveCriticalSection(&critAdd);
saveFile("Add item: " + std::to_string(temp->item));
}
_endthread();
}
void Find(void *)
{
List *temp = Head;
List *prevL;
while(true)
{
EnterCriticalSection(&critFind);
bool find = false;
temp = Head;
int number = rand() % 100 + 0;
saveFile("FIND number: " + std::to_string(number));
while(temp != NULL)
{
if (number == temp->item)
{
if(find){
prevL->Next = temp->Next;
}
else
{
saveFile("Number is found: " + std::to_string(temp->item));
find = true;
prevL = temp;
}
}
temp= temp->Next;
}
LeaveCriticalSection(&critFind);
}
delete temp;
_endthread();
}
int main(int argc, char** argv) {
InitializeCriticalSection(&critAdd);
InitializeCriticalSection(&critFile);
InitializeCriticalSection(&critFind);
AddThread = (HANDLE) _beginthread (Add, 1024, NULL);
FindThread = (HANDLE) _beginthread (Find, 1024, NULL);
getch();
DeleteCriticalSection(&critAdd);
DeleteCriticalSection(&critFile);
DeleteCriticalSection(&critFind);
return 0;
}
Критическая секция с очередью
#include <windows.h>
#include <process.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <conio.h>
#include <string>
#define SIZE 10
using namespace std;
//********************************************************
CRITICAL_SECTION critAdd, critFile, critDel;//initializing critical sections
HANDLE AddThread, DelThread, PrintThread; //thread initialization
ofstream logf;
//********************************************************
class Queue
{
private:
int front, rear, count;
int qlist[SIZE];
public:
Queue(void)// Queue initialization
{
front = 0;
rear = 0;
count = 0;
for(int i=0;i!= SIZE;i++)
{
qlist[i]=0;
}
}
void Qlnsert(const int item)// Adding to the queue
{
if (!QFull())// check if full
{
qlist[rear] = item;
rear++;
count++;
if (rear == SIZE)
{
rear = 0;
}
}
}
void QDelete(void)//Deleting from queue
{
if (!QEmpty())// check if empty
{
qlist[front] = 0;
front++;
count--;
if (front == SIZE)
{
front = 0;
}
}
}
void ClearQueue(void)// clear queue
{
front = 0;
rear = 0;
count = 0;
for (int i = 0; i != SIZE - 1;i++)
{
qlist[i] = 0;
}
}
int qPeek(void) // peek element in to the queue
{
int value = qlist[front];
QDelete();
return value;
}
void rebuild()//save elements,clear queue, adding to queue
{
int countBuf=this->count;
int buf[countBuf];
for(int i=0;i<countBuf;i++)
{
buf[i] = qPeek();
}
ClearQueue();
for(int i=1;i<countBuf;i++)
{
Qlnsert(buf[i]);
}
};
int get( int i) // get element by index
{
return qlist[i];
}
int QLength(void)//
{
return count;
}
bool QEmpty(void) // check if empty
{
if (count==0)
{
return true;
}
else
{
return false;
}
}
bool QFull(void) // check if full
{
if (SIZE==count)
{
return true;
}
else
{
return false;
}
}
};
//********************************************************
void saveFile(string str)// save to file
{
EnterCriticalSection(&critFile);
logf.open("log.txt",ios_base::app);
logf<<endl<<str;
logf.close();
LeaveCriticalSection(&critFile);
}
//********************************************************
Queue q;
//********************************************************
void Add(void *)//addition thread
{
int value;
srand(time(0));
while(true)
{
EnterCriticalSection(&critAdd);
if(q.QFull()==true)
{
saveFile(" Queue is full! ");
}
else
{
value = rand() % 100 + 1;
q.Qlnsert(value);
saveFile("Insert = " + std::to_string(value));
}
LeaveCriticalSection(&critAdd);
}
_endthread();
}
void Del(void *) //Delete thread
{
while(true)
{
EnterCriticalSection(&critDel);
if(q.QEmpty()==true)
{
saveFile(" Queue empty ");
}
else
{
saveFile(" Delete first element = " + std::to_string(q.get(0)));
q.rebuild();
}
LeaveCriticalSection(&critDel);
}
_endthread();
}
int main(int argc, char** argv)
{
InitializeCriticalSection(&critAdd);
InitializeCriticalSection(&critDel);
InitializeCriticalSection(&critFile);
AddThread = (HANDLE) _beginthread (Add, 1024, NULL);//create thread for Adding
DelThread = (HANDLE) _beginthread (Del, 1024, NULL);//create thread for Delete
getch();
DeleteCriticalSection(&critAdd);
DeleteCriticalSection(&critDel);
DeleteCriticalSection(&critFile);
return 0;
}
Семафор, читатель писатель, один процесс
#include <iostream>
#include <windows.h>
#include <process.h>
#include <ctime>
#include <conio.h>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
HANDLE s_write, // семафор, допускающий только одного писателя
s_acess, // семафор для учета и управления читателями
eOnRead; // событие - разрешение на подключение новых читателей
int am_readers=4;//макс. кол читателей
vector<int> vect;//разделяемый ресурс
CRITICAL_SECTION critFile;
ofstream logf;
void saveFile(string str)// save to file
{
EnterCriticalSection(&critFile);
logf.open("log.txt",ios_base::app);
logf<<endl<<str;
logf.close();
LeaveCriticalSection(&critFile);
}
//Поток "писатель"
DWORD WINAPI Writer(PVOID pParam)
{
int ind = *(int*)pParam;
int i=0;
//for (int i=0; i<10; i++)
while(true)
{
// ждем пока другой писатель закончит
WaitForSingleObject(s_write,INFINITE);
// запрещаем подключение новых читателей
ResetEvent(eOnRead);
// пишем
vect.push_back(i);
saveFile(std::to_string(ind)+" Writer :" + std::to_string(i));
//разрешаем новые чтения
SetEvent(eOnRead);
// разрешаем другим писать
ReleaseSemaphore(s_write,1,NULL);
i++;
}
}
DWORD WINAPI Reader(PVOID pParam)
{
HANDLE h[2];
h[0] = eOnRead;
h[1] = s_acess;
int ind = *(int*)pParam;
for(int i=0;i<vect.size();i++)
{
// ждем 1) разрешения на чтение (событие eOnRead) и
//2) свободную вакансию читателя (семафор s_acess)
WaitForMultipleObjects(2,h,true,INFINITE);
saveFile(std::to_string(ind)+" Reader :" + std::to_string(vect[i]));
ReleaseSemaphore(s_acess,1,NULL);
// освобождаем вакансию читателя
}
}
int menu()
{
int value;
int flag=0;
cout<<endl<<" 1. Write";
cout<<endl<<" 2. Read";
cout<<endl<<" 0. Exit";
cout<<endl<<" Your choice:";
do
{
cin>>value;
if(value<=2&&value>=0) flag=1;
}
while(flag==0);
cout<<endl;
return value;
}
int main(int argc, char** argv)
{
bool ex=false;
//список ид-ров потоков
vector<HANDLE> han;
//номера текущих читателей и писателей
int r_count=0;
int w_count=0;
//создаем семафоры и событие
InitializeCriticalSection(&critFile);
s_acess=CreateSemaphore(NULL,am_readers,am_readers,NULL);
s_write=CreateSemaphore(NULL,1,1,NULL);
eOnRead = CreateEvent(NULL,true,false,NULL);
while(!ex)
{
switch(menu())
{
case 2:
r_count++;
//запуск потока читателя
han.push_back(CreateThread(NULL,0,Reader,&r_count,0,NULL));
break;
case 1:
w_count++;
//запуск потока писателя
han.push_back(CreateThread(NULL,0,Writer,&w_count,0,NULL));
break;
case 0:
ex=true;
break;
}
}
//закрываем потоки перед выходом
DeleteCriticalSection(&critFile);
for(vector<HANDLE>::iterator it=han.begin();it<han.end();it++)
TerminateThread(*it,0);
return 0;
}
ПРОИЗВОДИТЕЛЬ-ПОТРЕБИТЕЛЬ
#include <iostream>
#include <windows.h>
#include <process.h>
#include <ctime>
#include <conio.h>
#include <fstream>
#include <vector>
#include <string>
#define bufferSize 2
using namespace std;
HANDLE empty, // семафор, допускающий только одного производителя
full,
mutex; // семафор для учета и управления потебителями
int max_consumers = 4; //макс. кол-во потребителей
int max_producers = 2;
//int bufferSize = 2;
int Buffer[bufferSize];
CRITICAL_SECTION critFile;
bool trans;
ofstream file;
void saveFile(string str) // запись в файл
{
EnterCriticalSection(&critFile);
file.open("log.txt",ios_base::app);
file<<endl<<str;
file.close();
LeaveCriticalSection(&critFile);
}
//Поток "производитель"
DWORD WINAPI Producer(PVOID pParam)
{
//int ind = *(int*)pParam;
int i = 0;
trans = true;
srand(time(NULL));
while(true)
{
WaitForSingleObject(empty,INFINITE);
WaitForSingleObject(mutex,INFINITE);
int value = rand() % 100 + 1;
saveFile(std::to_string(i)+" Producer : " + std::to_string(value));
for (int i = bufferSize-2; i >= 0; i--)
Buffer[i+1] = Buffer[i];
Buffer[0]=value;
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(full, 1, NULL);
i++;
}
}
//поток "потребитель"
DWORD WINAPI Consumer(PVOID pParam)
{
//int ind = *(int*)pParam;
int value;
int write;
int i = 0;
while(trans)
{
write = 0;
WaitForSingleObject(full, INFINITE);
WaitForSingleObject(mutex, INFINITE);
for (int i = bufferSize-1; i >= 0; i--)
if (Buffer[i] != 0)
{
write = i;
break;
}
value = Buffer[write];
Buffer[write]=0;
if (value != 0)
saveFile(std::to_string(i)+" Consumer :" + std::to_string(value));
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(empty, 1, NULL);
i++;
}
}
int main(int argc, char** argv)
{
InitializeCriticalSection(&critFile);
HANDLE hThreads[max_producers + max_consumers];
DWORD ThreadId;
int i;
mutex = CreateSemaphore(NULL, 1, 1,"Mutex");
full = CreateSemaphore(NULL, 0, bufferSize ,"Full");
empty = CreateSemaphore(NULL, bufferSize, bufferSize,"Empty");
for (i = 0; i < bufferSize; i++) Buffer[i] = 0;
for (i = 0; i < max_producers; i++)
hThreads[i]=CreateThread(0, 0, Producer, 0,0, &ThreadId);
for (i = 0; i < max_producers + max_consumers; i++)
hThreads[i] = CreateThread(0, 0, Consumer, 0, 0, &ThreadId);
WaitForMultipleObjects(max_producers, hThreads, true, INFINITE);
trans = false;
WaitForMultipleObjects(max_producers + max_consumers, hThreads, true, INFINITE);
DeleteCriticalSection(&critFile);
for (i = 0; i<max_producers + max_consumers; i++)
CloseHandle(hThreads[i]);
CloseHandle(mutex);
CloseHandle(full);
CloseHandle(empty);
getch();
return 0;
}
Мютекс, потоки
#include <windows.h>
#define THREADS_NUMBER 10
#define ITERATIONS_NUMBER 100
#define PAUSE 10 /* ms */
DWORD dwCounter = 0;
DWORD WINAPI ThreadProc(CONST LPVOID lpParam) {
CONST HANDLE hMutex = (CONST HANDLE)lpParam;
DWORD i;
for(i = 0; i < ITERATIONS_NUMBER; i++) {
WaitForSingleObject(hMutex, INFINITE);
dwCounter++;
ReleaseMutex(hMutex);
Sleep(PAUSE);
}
ExitThread(0);
}
VOID Error(CONST HANDLE hStdOut, CONST LPCWSTR szMessage) {
DWORD dwTemp;
TCHAR szError[256];
WriteConsole(hStdOut, szMessage, lstrlen(szMessage), &dwTemp, NULL);
wsprintf(szError, TEXT("LastError = %d\r\n"), GetLastError());
WriteConsole(hStdOut, szError, lstrlen(szError), &dwTemp, NULL);
ExitProcess(0);
}
INT main() {
TCHAR szMessage[256];
DWORD dwTemp, i;
HANDLE hThreads[THREADS_NUMBER];
CONST HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONST HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
if(NULL == hMutex) {
Error(hStdOut, TEXT("Failed to create mutex.\r\n"));
}
for(i = 0; i < THREADS_NUMBER; i++) {
hThreads[i] = CreateThread(NULL, 0, &ThreadProc, hMutex, 0, NULL);
if(NULL == hThreads[i]) {
Error(hStdOut, TEXT("Failed to create thread.\r\n"));
}
}
WaitForMultipleObjects(THREADS_NUMBER, hThreads, TRUE, INFINITE);
wsprintf(szMessage, TEXT("Counter = %d\r\n"), dwCounter);
WriteConsole(hStdOut, szMessage, lstrlen(szMessage), &dwTemp, NULL);
for(i = 0; i < THREADS_NUMBER; i++) {
CloseHandle(hThreads[i]);
}
CloseHandle(hMutex);
ExitProcess(0);
}
Семафор, многопоточность, читатель-писатель
1 прога
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
const LPCWSTR Name = L"ReadersSemaphore";
HANDLE hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE SemReaderHandle = CreateSemaphore(NULL,1,1,Name);
HANDLE hWriter,hSaver,hPrinter;
DWORD thID,thID2,thID3;
class Base;
void Show(pair<bool,string>);
void SaveToFile(Base*);
void Writer(Base*);
void PrintToConsole(Base*);
//-------------------------------------------------------------------------
class Base{
vector <pair<bool,string>> vect;
public:
void Add(pair<bool,string> _what)
{
vect.push_back(_what);
}
int Count()
{
return vect.size();
}
pair<bool,string>& operator[](int index)
{
return vect[index];
}
void Print()
{
vector <pair<bool,string>> ::iterator it = vect.begin();
vector <pair<bool,string>> ::iterator endit;
do{
WaitForSingleObject(SemReaderHandle,INFINITE);
endit = vect.end();
ReleaseSemaphore(SemReaderHandle,1,NULL);
}while(it==endit);
while(true)
{
WaitForSingleObject(SemReaderHandle,INFINITE);
if(it->first)
{
SetConsoleTextAttribute(hConsoleHandle, FOREGROUND_GREEN);
cout<<it->second<<'\n';
SetConsoleTextAttribute(hConsoleHandle, 7);
}
else
{
SetConsoleTextAttribute(hConsoleHandle, FOREGROUND_RED);
cout<<it->second<<'\n';
SetConsoleTextAttribute(hConsoleHandle, 7);
}
if(++it==vect.end())
break;
ReleaseSemaphore(SemReaderHandle,1,NULL);
}
ReleaseSemaphore(SemReaderHandle,1,NULL);
}
bool LoadFromFile()
{
string FileName = "D:\\textfile.txt",Line;;
ifstream File(FileName.c_str());
if(!File)
return false; //ошибка открытия файла
else
while(getline(File,Line))
Add(pair<bool,string>(true,Line));
return true;
}
bool SaveToFile()
{
string FileName = "D:\\output.txt";
ofstream File(FileName.c_str());
if(!File)
return false;
else
{
vector <pair<bool,string>> ::iterator it = vect.begin();
vector <pair<bool,string>> ::iterator endit;
do{
WaitForSingleObject(SemReaderHandle,INFINITE);
endit = vect.end();
ReleaseSemaphore(SemReaderHandle,1,NULL);
}while(it==endit);
while(true)
{
WaitForSingleObject(SemReaderHandle,INFINITE);
File<<it->second<<'\n';
if(it++==vect.end()-1)
{
ReleaseSemaphore(SemReaderHandle,1,NULL);
break;
}
ReleaseSemaphore(SemReaderHandle,1,NULL);
}
return true;
}
}
};
//----------------------------------------------------------------------------------
void SaveToFile(Base* b)
{
b->SaveToFile();
}
void Writer(Base* res)
{
do
if(res->Count()>5)
{
WaitForSingleObject( SemReaderHandle, INFINITE );
res->operator[](abs(rand()%res->Count()-1)) = pair<bool,string>(false,"bla-bla-bla, i made something bad with this string");
ReleaseSemaphore(SemReaderHandle,1,NULL);
}
while(true);
}
void PrintToConsole(Base* b)
{
b->Print();
}
2 прога
#include "stdafx.h"
#include "header.h"
void main()
{
Base q;
hSaver = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SaveToFile, &q, CREATE_SUSPENDED, &thID2);
hWriter = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Writer, &q, CREATE_SUSPENDED, &thID);
hPrinter = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PrintToConsole, &q, CREATE_SUSPENDED, &thID3);
if(q.LoadFromFile())
{
ResumeThread(hWriter);
ResumeThread(hSaver);
ResumeThread(hPrinter);
HANDLE handles[3] = {hSaver,SemReaderHandle,hPrinter};
WaitForMultipleObjects(3,handles, true,INFINITE);
TerminateThread(hWriter,0);
}
else cout<<"File openning eror\n";
system("pause");
CloseHandle(SemReaderHandle);
}