Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <getopt.h>
- #include <unistd.h>
- #define down pthread_mutex_lock
- #define up pthread_mutex_unlock
- #define signal pthread_cond_signal
- #define wait pthread_cond_wait
- #define broadcast pthread_cond_broadcast
- typedef struct person{
- int id;
- enum{
- client,
- detective
- } type;
- } person_t;
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t detective_condition = PTHREAD_COND_INITIALIZER;
- pthread_cond_t client_condition = PTHREAD_COND_INITIALIZER;
- pthread_cond_t ready = PTHREAD_COND_INITIALIZER;
- int client_count = 0;
- int detective_count = 0;
- int client_temp = 0;
- int detective_temp = 0;
- int ready_to_go = 0;
- // ----
- void *client_visit_bar(void *ptr){
- person_t *person = (person_t *) ptr;
- down(&mutex);
- (void) printf("bar: %d c %d d c%d entering\n",
- client_count, detective_count, person->id);
- while (ready_to_go == 1){
- wait(&ready, &mutex);
- }
- while (detective_count > 0){
- detective_count--;
- signal(&detective_condition);
- }
- while (detective_count <= 0){
- client_count++;
- (void) printf("bar: %d c %d d c%d waiting...\n",
- client_count, detective_count, person->id);
- wait(&client_condition, &mutex);
- (void) printf("bar: %d c %d d ... c%d waking up\n",
- client_count, detective_count, person->id);
- }
- while (!client_count){
- broadcast(&ready);
- ready_to_go = 0;
- }
- (void) printf("bar: %d c %d d c%d leaving\n",
- client_count, detective_count, person->id);
- up(&mutex);
- return NULL;
- }
- // ----
- void *detective_visit_bar(void *ptr){
- person_t *person = (person_t *) ptr;
- down(&mutex);
- (void) printf("bar: %d c %d d d%d entering\n",
- client_count, detective_count, person->id);
- while (ready_to_go == 1){
- wait(&ready, &mutex);
- }
- while (client_count > 0){
- client_count = 0;
- (void) printf("bar: %d c %d d d%d leaving (+ picking everyone)\n",
- client_count, detective_count, person->id);
- ready_to_go = 1;
- broadcast(&client_condition);
- }
- while(client_count <= 0){
- detective_count++;
- (void) printf("bar: %d c %d d d%d talking...\n",
- client_count, detective_count, person->id);
- wait(&detective_condition, &mutex);
- (void) printf("bar: %d c %d d d%d waking up\n",
- client_count, detective_count, person->id);
- (void) printf("bar: %d c %d d d%d leaving\n",
- client_count, detective_count, person->id);
- }
- up(&mutex);
- return NULL;
- }
- // ----
- static void* enjoy_life(void *ptr){
- person_t *person = (person_t*) ptr;
- while(1)
- {
- switch (person->type)
- {
- case client:
- detective_visit_bar(ptr);
- break;
- case detective:
- client_visit_bar(ptr);
- break;
- }
- usleep(random()%100000);
- }
- return NULL;
- }
- // ----
- int main(int argc, char** argv){
- int opt, i, status, client_total = 1, detective_total = 1;
- //person_t *person = NULL;
- while ((opt = getopt(argc, argv, "c:d:")) != -1){
- // : consider another argument after
- switch (opt){
- case 'c':
- client_total = atoi(optarg); // set num of clients
- if (client_total <= 0){
- fprintf(stderr, "invalid number of people\n");
- return EXIT_FAILURE;
- }
- break;
- case 'd':
- detective_total = atoi(optarg); // set num of detectives
- if (detective_total <= 0){
- fprintf(stderr, "invalid number of iterations\n");
- return EXIT_FAILURE;
- }
- break;
- }
- }
- int total_people = client_total+detective_total;
- pthread_t people[total_people];
- person_t *clients;
- clients = malloc(client_total * sizeof(person_t));
- if(!clients) // check correct memory allocation
- return EXIT_FAILURE;
- person_t *detectives;
- detectives = malloc(detective_total * sizeof(person_t));
- if(!detectives) // check correct memory allocation
- return EXIT_FAILURE;
- /*
- pthread_t client[client_total], detective[detective_total];
- */
- for(i=0;i<client_total;i++){
- (clients+i)->type = client;
- (clients+i)->id = i;
- }
- for(i=0;i<detective_total;i++){
- (detectives+i)->type = detective;
- (detectives+i)->id = i;
- }
- for (i=0;i<total_people;i++){
- if (i<client_total)
- status = pthread_create(&people[i],NULL,enjoy_life,(void*)(clients+i));
- else
- status = pthread_create(&people[i],NULL,enjoy_life,(void*)(detectives+i-client_total));
- if (status){
- fprintf(stderr,"failed to create thread");
- return EXIT_FAILURE;
- }
- }
- for (i=0;i<total_people;i++){
- if(people[i]){
- status = pthread_join(people[i],NULL);
- if (status){
- fprintf(stderr,"failed to join thread");
- }
- }
- }
- free(clients);
- free(detectives);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement