经典互斥问题模拟--单车道过桥--模拟代码

来源:互联网 发布:网络授权查询系统 编辑:程序博客网 时间:2024/05/10 17:19

实习作业:多线程基础编程实践


pass_bridge.cpp


/** compile: g++ -o pass_bridge.out pass_bridge.cpp -lpthread* run: ./pass_bridge.out*this programe should run on a linux OS ****/ //head files #include <sys/socket.h>  #include <sys/types.h>  #include <poll.h>               #include <unistd.h>          #include <netdb.h>           #include <error.h>           #include <stdlib.h>  #include <time.h>  #include <stdio.h>  #include <errno.h>  #include <string.h>  #include <netdb.h>  #include <netinet/in.h>  #include <arpa/inet.h> #include <pthread.h> #include <list> #include <iterator> #include <algorithm> #include "randutil.h"#include "car.h"//init parampthread_mutex_t mutex1; //use when changing count1pthread_mutex_t mutex2; //use when changing count2pthread_mutex_t output; //use when the programe needs outputint count1 = 0; //the number of cars waiting on the leftside to pass through the bridgeint count2 = 0; // cars waiting on the right side .../*  *-1 stands for no cars requests for passing*Car::LEFT_TO_RIGHT means cars waiting on the left side got the chance to passing through *Car::RIGHT_TO_LEFT means cars waiting on the right side got the chance to passing through*/ int state=-1; std::list<Car *> cars;//configure infoint pass_sleep_time_width = 3;int car_join_sleep_time_width = 3;#define NUM_CARS 20 //number of cars int car_seq_width = 3;Car arr_cars[NUM_CARS];//comparator bool CompareRules(Car* x,  Car* y){if(x->sq < y->sq)return true;elsereturn false;}//show the state of the bridge void show_state(){//printf("state = %d\n",state);cars.sort(CompareRules); std::list<Car *>::iterator it=cars.begin();for(;it!=cars.end();it++){if((*it)->state == Car::WAIT && (*it)->dir == Car::LEFT_TO_RIGHT)printf("[%d] ",(*it)->id);}if(state == Car::LEFT_TO_RIGHT)printf(" -> ");else if(state == Car::RIGHT_TO_LEFT)printf(" <- ");if(state == -1)printf(" -- ---- --");else{it=cars.begin();for(;it!=cars.end();it++){if((*it)->state == Car::PASSING)printf("[%d] ",(*it)->id);}}if(state == Car::LEFT_TO_RIGHT)printf(" -> ");else if(state == Car::RIGHT_TO_LEFT)printf(" <- ");it=cars.begin();for(;it!=cars.end();it++){if((*it)->state == Car::WAIT && (*it)->dir == Car::RIGHT_TO_LEFT)printf("[%d] ",(*it)->id);}puts("");}void *left_to_right(void * arg){     Car * c = &arr_cars[*((int *)arg)];          pthread_mutex_lock(&output);     c->pass();     c->state=Car::WAIT;     pthread_mutex_unlock(&output);      pthread_mutex_lock(&output);     show_state();     pthread_mutex_unlock(&output);     //P(S1)     pthread_mutex_lock(&mutex1);         //IF(COUNT1==0)     if(count1==0){     //P(S2)            pthread_mutex_lock(&mutex2);            state = Car::LEFT_TO_RIGHT;     }    //COUNT1++     count1++;     //V(S1)     pthread_mutex_unlock(&mutex1);     //PASSING THROUGH     pthread_mutex_lock(&output);     c->passing();     c->state=Car::PASSING;     pthread_mutex_unlock(&output);      pthread_mutex_lock(&output);     show_state();     pthread_mutex_unlock(&output);     usleep(RANDOM::getNumber(pass_sleep_time_width));          //P(S1)     pthread_mutex_lock(&mutex1);     //COUNT1--     count1--;     //IF(COUNT1==0)     if(count1==0){     //V(S2)            pthread_mutex_unlock(&mutex2);            state = -1;     }     //V(S1)     pthread_mutex_unlock(&mutex1);          pthread_mutex_lock(&output);     c->passed();     c->state=Car::PASSED;     pthread_mutex_unlock(&output);      pthread_mutex_lock(&output);     show_state();     pthread_mutex_unlock(&output);     pthread_exit(0);}void *right_to_left(void * arg){     Car * c = &arr_cars[*((int *)arg)];     pthread_mutex_lock(&output);     c->pass();     c->state=Car::WAIT;     pthread_mutex_unlock(&output);      pthread_mutex_lock(&output);     show_state();     pthread_mutex_unlock(&output);     //P(S2)     pthread_mutex_lock(&mutex2);     //IF(COUNT2==0)     if(count2==0){     //P(S1)            pthread_mutex_lock(&mutex1);            state = Car::RIGHT_TO_LEFT;     }     //COUNT2++     count2++;     //V(S2)     pthread_mutex_unlock(&mutex2);     //PASSING THROUGH          pthread_mutex_lock(&output);     c->passing();     c->state=Car::PASSING;     pthread_mutex_unlock(&output);      pthread_mutex_lock(&output);     show_state();     pthread_mutex_unlock(&output);     usleep(RANDOM::getNumber(pass_sleep_time_width));          //P(S2)     pthread_mutex_lock(&mutex2);     //COUNT2--     count2--;     //IF(COUNT2==0)     if(count2==0){     //V(S1)            pthread_mutex_unlock(&mutex1);            state = -1;     }     //V(S2)     pthread_mutex_unlock(&mutex2);          pthread_mutex_lock(&output);     c->passed();     c->state=Car::PASSED;     pthread_mutex_unlock(&output);      pthread_mutex_unlock(&output);     show_state();     pthread_mutex_unlock(&output);     pthread_exit(0);}int main(){        pthread_t tid1,tid2;    int num=0;    for(int i=0;i<NUM_CARS;i++)    {    arr_cars[i].id = RANDOM::getNumber(car_seq_width);    arr_cars[i].sq = ++num;cars.push_back(&arr_cars[i]);    }    std::list<Car *>::iterator it=cars.begin();    int num_cars = NUM_CARS;    num = 0;    while(num_cars--){             int who = RANDOM::getNumber(2);             if(who%2==0){(*it)->dir = Car::LEFT_TO_RIGHT;pthread_create(&tid1,NULL,left_to_right,&num);               }             else             {(*it)->dir = Car::RIGHT_TO_LEFT;pthread_create(&tid2,NULL,right_to_left,&num);               }             usleep(RANDOM::getNumber(car_join_sleep_time_width));             num++;             it++;    }    return 0;    }



car.h


#include <stdio.h> class Car{      public:       static const int LEFT_TO_RIGHT = 0;       static const int RIGHT_TO_LEFT = 1;              static const int OUT = 0;       static const int WAIT = 1;       static const int PASSING = 2;       static const int PASSED = 3;              int dir;        int id;       int sq;       int state;              Car(){}              Car(int id,int dir,int num)       {            sq = num;            this->id=id;            this->dir=dir;            state = Car::OUT;       }              Car(int id,int num)       {            sq = num;            this->id=id;            state = Car::OUT;       }                    void pass()       {            if(dir==Car::LEFT_TO_RIGHT)            {                   printf(">-- :car %d requests for passing\n",this->id);                           }            else            {                   printf("--< :car %d requests for passing\n",this->id);            }       }              void passing()       {            if(dir==Car::LEFT_TO_RIGHT)            {                   printf("->- :car %d is passing\n",this->id);                           }            else            {                   printf("-<- :car %d is passing\n",this->id);            }       }              void passed()       {            if(dir==Car::LEFT_TO_RIGHT)            {                   printf("--> :car %d has passed\n",this->id);                           }            else            {                   printf("<-- :car %d has passed\n",this->id);            }       }       };




randutil.h


#include <stdlib.h>  #include <time.h>    class RANDOM   {          public:                 //width stands for its width                   static long getNumber(int width)                  {                            width--;                          long ret=0;                          ret = rand()%9+1;                          long range=1;                          while(width--)                          {                                  ret*=10;                                  range*=10;                          }                          return ret+rand()%range;                    }  };  



运行结果:


[root@bogon mutex]# g++ -o pass_bridge.out pass_bridge.cpp -lpthread[root@bogon mutex]# ./pass_bridge.out --< :car 286 requests for passing -- ---- --[286] -<- :car 286 is passing <- [286]  <- <-- :car 286 has passed -- ---- -->-- :car 115 requests for passing[115]  -- ---- --->- :car 115 is passing -> [115]  -> --> :car 115 has passed -- ---- -->-- :car 635 requests for passing[635]  -- ---- --->- :car 635 is passing -> [635]  -> --> :car 635 has passed -- ---- ----< :car 292 requests for passing -- ---- --[292] -<- :car 292 is passing <- [292]  <- <-- :car 292 has passed -- ---- ----< :car 721 requests for passing -- ---- --[721] -<- :car 721 is passing <- [721]  <- <-- :car 721 has passed -- ---- ----< :car 627 requests for passing -- ---- --[627] -<- :car 627 is passing <- [627]  <- <-- :car 627 has passed -- ---- -->-- :car 659 requests for passing[659]  -- ---- --->- :car 659 is passing -> [659]  -> >-- :car 626 requests for passing[626]  -> [659]  -> ->- :car 626 is passing -> [659] [626]  -> --> :car 659 has passed -> [626]  -> --> :car 626 has passed -- ---- ----< :car 726 requests for passing -- ---- --[726] -<- :car 726 is passing <- [726]  <- <-- :car 726 has passed -- ---- -->-- :car 836 requests for passing[836]  -- ---- --->- :car 836 is passing -> [836]  -> --> :car 836 has passed -- ---- -->-- :car 968 requests for passing[968]  -- ---- --->- :car 968 is passing -> [968]  -> >-- :car 729 requests for passing[729]  -> [968]  -> ->- :car 729 is passing -> [968] [729]  -> --> :car 968 has passed -> [729]  -> >-- :car 930 requests for passing[930]  -- ---- --->- :car 930 is passing -> [729] [930]  -> --> :car 729 has passed -> [930]  -> --> :car 930 has passed -- ---- ----< :car 923 requests for passing -- ---- --[923] -<- :car 923 is passing <- [923]  <- <-- :car 923 has passed -- ---- ----< :car 235 requests for passing -- ---- --[235] -<- :car 235 is passing <- [235]  <- >-- :car 602 requests for passing[602]  <- [235]  <- <-- :car 235 has passed[602]  -- ---- --->- :car 602 is passing -> [602]  -> --> :car 602 has passed -- ---- ----< :car 158 requests for passing -- ---- --[158] -<- :car 158 is passing <- [158]  <- <-- :car 158 has passed -- ---- ----< :car 667 requests for passing -- ---- --[667] -<- :car 667 is passing <- [667]  <- <-- :car 667 has passed -- ---- ----< :car 256 requests for passing -- ---- --[256] -<- :car 256 is passing <- [256]  <- --< :car 542 requests for passing -- ---- --[542] -<- :car 542 is passing <- [256] [542]  <- <-- :car 256 has passed <- [542]  <- 


0 0
原创粉丝点击