Piszę program w oparciu o bibliotekę pthread. Program ma symulować imprezę masową. Do tej pory (kod poniżej) tworzę wątki uczestników i ochroniarzy, którzy się przemieszczają po miejscu w którym znajduje się impreza. Wątki zajmują określone miejsca w jednym miejscu może stać jeden uczestnik i jeden ochroniarz.

Docelowo ochroniarze mają sprawdzać stopień upicia uczetników. Uczestnicy będą mieli startowy poziom upicia przy wejściu. Teraz jak zrobić aby

  • poziom upicia spadał o określoną ilość wraz z określonym czasem?
  • jak ustawić uczestników (wątki) w kolejce? (ma to być kolejka do baru, gdy będą chciały wypić więcej)
/*
sudo apt-get install ncurses-dev
g++ src.cpp -o program -lcurses -lpthread -std=gnu++11

*/


#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <ncurses.h>
//#include <Windows.h>

using namespace std;

#define NUM_THREADS_UCZ    10
#define NUM_THREADS_OCH    5
const int N = 5;
pthread_mutex_t lock;
pthread_mutex_t ochr;
int poczekalnia = 5000000;

struct pole {
	bool poz1=0;
	bool poz2=0;
};

pole miejsceImprezy[N][N];


/*

Funkcja wypisuje tablicę -"rozmieszczenie ludzi na imprezie"
*/
void WypiszTab(){
	for (int i=0; i<N; i++){
		for (int j=0; j<N; j++){
			if ( miejsceImprezy[i][j].poz1==true && miejsceImprezy[i][j].poz2==true)
				cout << "+";
			else if ( miejsceImprezy[i][j].poz1==true )
			cout << "*";
			else if ( miejsceImprezy[i][j].poz2==true )
			cout << "o";
			else
				cout << "0";
		}
		cout <<endl;
	}

	cout <<endl;

}

/*
struktura z danymi wątka uczesntik
*/

struct uczestnikThreadData {
	int threadId;
	int upicie;
	int x;
	int y;
};

uczestnikThreadData uczestnikThreadDataArray[NUM_THREADS_UCZ];

/*
struktura z danymi wątka ochroniarz
*/



struct ochroniarzThreadData{
	int threadId;
	int x;
	int y;
};

ochroniarzThreadData ochroniarzThreadDataArray[NUM_THREADS_OCH];

int couter=0;

void losuj(int &a, int &b){
	a=rand()%N;
	b=rand()%N;
}

/*
Funkcja zmienia miejsce uczestnika na imprezie
*/

void* ZmienMiejsceUczestnik(void *arg){

while(1)
  {
   pthread_mutex_lock(&lock);
   
   uczestnikThreadData *my_data;
  
   my_data = (struct uczestnikThreadData *) arg;
   int xOld = my_data -> x;
   int yOld = my_data->y;

   losuj(my_data -> x,my_data -> y);

   couter++;
   while(1) {
	   if(miejsceImprezy[my_data->x][my_data->y].poz1)
		   losuj(my_data -> x,my_data -> y);
	   else{
		   miejsceImprezy[my_data->x][my_data->y].poz1=true;
		   break;
	   }
   }
      
   miejsceImprezy[xOld][yOld].poz1=false;

   WypiszTab();
   pthread_mutex_unlock(&lock);
   

   int tmp = rand()%poczekalnia;	

   usleep(tmp*my_data->threadId);

  }
   pthread_exit(0);
     

   return NULL;
}

/*
Funkcja zmienia miejsce ochroniarza na imprezie
*/


void* ZmienMiejsceOchroniarz(void *arg){

while(1)
  {

   pthread_mutex_lock(&lock);
   pthread_mutex_lock(&ochr);
   ochroniarzThreadData *my_data;
  
   my_data = (struct ochroniarzThreadData *) arg;
   int xOld = my_data -> x;
   int yOld = my_data->y;

   losuj(my_data -> x,my_data -> y);

   couter++;
   while(1) {
	   if(miejsceImprezy[my_data->x][my_data->y].poz2)
		   losuj(my_data -> x,my_data -> y);
	   else{
		   miejsceImprezy[my_data->x][my_data->y].poz2=true;
		   break;
	   }
   }
      
   miejsceImprezy[xOld][yOld].poz2=false;

   WypiszTab();
   pthread_mutex_unlock(&lock);
   pthread_mutex_unlock(&ochr);
   int tmp = rand()%poczekalnia;	

   usleep(tmp*my_data->threadId);
  }
   pthread_exit(0);
     

   return NULL;
}

		

int main ()
{
	srand(time(NULL));
	pthread_t threads_ucz[NUM_THREADS_UCZ];
	pthread_t threads_och[NUM_THREADS_OCH];

	if (pthread_mutex_init(&lock, NULL) != 0)
	    {
		printf("\n mutex init failed\n");
		return 1;
	    }

	WypiszTab();
	int p=0;

	
		for (int t=0; t<NUM_THREADS_UCZ; t++)
		{
		uczestnikThreadDataArray[t].threadId=t;
		pthread_create(&threads_ucz[t], NULL, ZmienMiejsceUczestnik, (void *) &uczestnikThreadDataArray[t]);
		}

	for (int t2=0; t2<NUM_THREADS_OCH; t2++)
	{
	ochroniarzThreadDataArray[t2].threadId=t2;
	pthread_create(&threads_och[t2], NULL, ZmienMiejsceOchroniarz, (void *) &ochroniarzThreadDataArray[t2]);
	}



	for (int i=0; i< NUM_THREADS_UCZ; i++)
	pthread_join(threads_ucz[i], NULL);

	for (int i=0; i< NUM_THREADS_OCH; i++)
	pthread_join(threads_och[i], NULL);
	cout <<couter;

}