code

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);

}

 

Report Page