#include #include #include #include #define DEBUG 1 #define MAX_DATA 12 #define SUBWAYS 4 typedef struct subway{ double nStartDistance[SUBWAYS]; double nNowDistance[SUBWAYS]; double nSpeed[SUBWAYS]; }subway_t; void ReadLine(int Line); void StartThread(int Subway); static void *GoSubwayGo(void *index); void PrintList(int Subway); void Usage(); FILE *file; subway_t value; pthread_t th[SUBWAYS]; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond; char *pProgname; char *pFilename; int GlobalSubway; int main(int argc, char *argv[]) { char cBuffer[MAX_DATA]; int nCount; pProgname = argv[0]; if(argc != 2) { Usage(); return EXIT_FAILURE; } pFilename = argv[1]; if((file = fopen(pFilename, "r")) == NULL) { fprintf(stderr, "%s: Can't open file %s\n", pProgname, pFilename); return EXIT_FAILURE; } for(nCount = 0; nCount < SUBWAYS; nCount++) { ReadLine(nCount); } #if DEBUG for(nCount = 0; nCount < SUBWAYS; nCount++) PrintList(nCount); #endif while((cBuffer[0] = getchar()) != 'S') { continue; } for(nCount = 0; nCount < SUBWAYS; nCount++) { GlobalSubway = nCount; StartThread(nCount); } for(nCount = 0; nCount < SUBWAYS; nCount++) { pthread_join(th[nCount], NULL); } #if DEBUG for(nCount = 0; nCount < SUBWAYS; nCount++) PrintList(nCount); #endif return EXIT_SUCCESS; } void ReadLine(int Line) { char cBuffer[MAX_DATA]; if(fgets(cBuffer, MAX_DATA -1, file) == NULL) { fprintf(stderr, "%s: invalid file layout %s\n", pProgname, pFilename); exit(EXIT_FAILURE); } sscanf(cBuffer,"%lf %lf", &value.nStartDistance[Line], &value.nSpeed[Line]); value.nNowDistance[Line] = value.nStartDistance[Line] * 1000; value.nSpeed[Line] = value.nSpeed[Line] / 3.6; } void StartThread(int Subway) { char cBuffer[255]; sprintf(cBuffer,"%d", Subway); #if DEBUG printf("cBuffer: %s\n", cBuffer); #endif if(pthread_create(&th[Subway], NULL, &GoSubwayGo, cBuffer) != 0) { fprintf(stderr, "%s: Error creating Thread\n", pProgname); exit(EXIT_FAILURE); } } static void *GoSubwayGo(void *index) { int Status; int Subway; int GotWhere = 1; printf("index: %s\n", (char *) index); Subway = (int) strtol((char *) index, NULL, 10); Subway = GlobalSubway; printf("Subway %d started\n", Subway); while (GotWhere != 0) { #if DEBUG printf("Subway: %d\n", Subway); #endif if((Status = pthread_mutex_lock(&mutex)) != 0); { fprintf(stderr,"%s: Error Mutex_Lock with Tread %ld\n", pProgname, pthread_self()); exit(EXIT_FAILURE); } if(value.nNowDistance[Subway] >= value.nSpeed[Subway]) { value.nNowDistance[Subway] = value.nNowDistance[Subway] - value.nSpeed[Subway]; } else { value.nNowDistance[Subway] = 0; pthread_cond_wait(&cond, &mutex); } GotWhere = value.nNowDistance[Subway]; if((Status = pthread_mutex_unlock(&mutex)) != 0) { fprintf(stderr,"%s: Error Mutex_Unlock with Tread %ld\n", pProgname, pthread_self()); exit(EXIT_FAILURE); } sleep (1); } pthread_exit((void *) 0); } void PrintList(int Subway) { printf("%d: StartDistance: %.2lf km, NowDistance: %.2lf m, Speed: %.2lf m/s\n", Subway, value.nStartDistance[Subway], value.nNowDistance[Subway], value.nSpeed[Subway]); } void Usage() { printf("Usage %s:\n", pProgname); printf("%s filename\n", pProgname); }