#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); void *GoSubwayGo(void *index); void PrintList(int Subway); void Usage(); FILE *file; subway_t value; pthread_t thread1, thread2, thread3, thread4; 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; int Subway; 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; } Subway = 0; if(pthread_create(&thread1, NULL, &GoSubwayGo, &Subway) != 0) { fprintf(stderr, "%s: Error creating Thread\n", pProgname); exit(EXIT_FAILURE); } pthread_join(thread1, NULL); Subway = 1; if(pthread_create(&thread2, NULL, &GoSubwayGo, &Subway) != 0) { fprintf(stderr, "%s: Error creating Thread\n", pProgname); exit(EXIT_FAILURE); } pthread_join(thread2, NULL); Subway = 2; if(pthread_create(&thread3, NULL, &GoSubwayGo, &Subway) != 0) { fprintf(stderr, "%s: Error creating Thread\n", pProgname); exit(EXIT_FAILURE); } pthread_join(thread3, NULL); Subway = 3; if(pthread_create(&thread4, NULL, &GoSubwayGo, &Subway) != 0) { fprintf(stderr, "%s: Error creating Thread\n", pProgname); exit(EXIT_FAILURE); } pthread_join(thread4, 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 *GoSubwayGo(void *index) { int Status; int GotWhere = 1; printf("Subway %d started\n", *((int *) (index))); while (GotWhere != 0) { #if DEBUG printf("Subway: %d\n", *((int *) (index))); #endif pthread_detach(pthread_self()); Status = pthread_mutex_lock(&mutex); if(value.nNowDistance[*((int *) (index))] >= value.nSpeed[*((int *) (index))]) { value.nNowDistance[*((int *) (index))] = value.nNowDistance[*((int *) (index))] - value.nSpeed[*((int *) (index))]; } else { value.nNowDistance[*((int *) (index))] = 0; pthread_cond_wait(&cond, &mutex); } GotWhere = value.nNowDistance[*((int *) (index))]; Status = pthread_mutex_unlock(&mutex); sleep (1); } return NULL; } 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); }