computeras13 Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Καλησπέρα σε όλους. Προσπαθώ να γράψω ένα πρόγραμμα (μια εργασία για την ακρίβεια) που έχει να κάνει με pthreads σε c. Το θέμα μου δεν είναι εκεί όμως. Μιας και έχω καιρό να ασχοληθώ με c έχω μπλέξει λίγο τα μπούτια μου με (τι άλλο pointers. Για την ακρίβεια μέσα σε μια function δημιουργώ έναν πίνακα από μια δομή που έχω φτιάξει ως εξής >markers mrks[K]; Η δομή είναι η >typedef struct { pthread_mutex_t* mutex; int markerID; } markers; Στην συνέχεια ο πίνακας αυτός πρέπει να γεμίσει μέσα από μια άλλη συνάρτηση την οποία καλώ ως >getMarkers(studentID,mrks) Αυτή με την σειρά της κάνει κάποιες άλλες κλήσεις με σκοπό να βρει τα κατάλληλα δεδομένα και να γεμίσει τον πίνακα. Κατά την διάρκεια που ο κώδικας είναι μέσα σε αυτή την function οι τιμές είναι κανονικές. Όταν όμως επιστρέφουν πίσω στην αρχική function δεν είναι οι ίδιες (είναι αόριστες). Μπορεί κάποιος/α να ρίξει λίγο τα φώτα του (να μου δώσει έστω μια κατεύθυνση για το τι μπορεί να φταίει; Παραθέτω και ολόκληρο τον κώδικα μήπως και προσφέρει περισσότερη βοήθεια. >// Skeleton program for project marking problem, COMSM2001 Assignment 1 #include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <time.h> #include <sys/time.h> int S; // Number of students int M; // Number of markers volatile int K; // Number of markers per demo int N; // Number of demos per marker int T; // Length of session (minutes) int D; // Length of demo (minutes) // S*K <= M*N // D <= T typedef struct { pthread_mutex_t* mutex; int markerID; } markers; markers *AM; /* Holds the Available Markers */ pthread_cond_t *COND; /* Conditions that are used to sync between the markers and students (index is the markerID) */ int *MAPPINGS; /* Mappings between the markers and the students (markerID as index and studentID as value) */ int AMindex = 0; /* The current index in the Available Markers Array */ int AMlast = 0; /* The last inserted index in the Available Markers Array */ int TIMEOUT = 0; /* Indicates whether or not a timeout has occured */ pthread_mutex_t grabbing = PTHREAD_MUTEX_INITIALIZER; /* A mutex so that only one student at a time can grab markers */ // ###################### // #Additional functions# // ###################### // Add a marker (mutex) as available addAvailableMarker(pthread_mutex_t* mutex, int markerID){ AM[AMlast%M].mutex=mutex; AM[AMlast%M].markerID=markerID; printf("-----> Marker %d has been marked as available at index %d <-----\n",markerID,AMlast); AMlast++; } // Get the next available marker (mutex) int getAvailableMarker(markers** mrk){ if(AMindex==AMlast) return 0; // no available marker /* printf("-----> Trying to get marker from position %d <-----\n",AMindex%M);*/ *mrk = &(AM[AMindex%M]); printf("-----> Found available marker at position %d who is %d <-----\n",AMindex%M,*mrk); AMindex++; return 1; // available marker found and returned } int getMarkers(int studentID, markers *M){ // A local markers array of size K int count=0; pthread_mutex_lock(&grabbing); while(count<K){ if(getAvailableMarker(&((&M)[count]))) count++; if(TIMEOUT) break; } printf("-----> Got markers %d and %d <-----\n",(&M)[0],(&M)[1]); pthread_mutex_unlock(&grabbing); return !TIMEOUT; } lockMarkers(markers* M,int studentID){ int i; for(i = 0; i < K; i++){ printf("-----> Student %d trying to lock mutex %d that is in struct markers %d <-----\n",studentID,(&M)[i],M[i]); /* pthread_mutex_lock(M[i].mutex); // Lock the mutex*/ /* MAPPINGS[M[i].markerID] = studentID; // Update the MAPPINGS array*/ /* pthread_cond_signal(&(COND[M[i].markerID])); // Signal the markers*/ /* pthread_cond_wait(&(COND[M[i].markerID]),M[i].mutex); // Wait for the marker thread to printf(...grabbed by...)*/ } } unlockMarkers(markers* M){ int i; for (i = 0; i < K; i++) { pthread_cond_signal(&(COND[M[i].markerID])); // Signal the marker thread that the presentation has finished pthread_mutex_unlock(M[i].mutex); // Unlock marker mutex } } // ############################# // #End of Additional Functions# // ############################# struct timeval starttime; // timenow(): returns current simulated time in "minutes" (cs) int timenow() { struct timeval now; gettimeofday(&now, NULL); return (now.tv_sec-starttime.tv_sec)*100 + (now.tv_usec-starttime.tv_usec)/10000; } // delay(t): delays for t "minutes" (cs) void delay(int t) { struct timespec rqtp, rmtp; t *= 10; rqtp.tv_sec = t / 1000; rqtp.tv_nsec = 1000000 * (t % 1000); nanosleep(&rqtp, &rmtp); } // panic(): simulates a student's panicking activity void panic() { delay(random()%(T-D)); } // demo(): simulates a demo activity void demo() { delay(D); } // marker(arg): marker thread void *marker(void *arg) { int markerID = *(int *)arg; int job, studentID; printf("%d marker %d: enters lab\n", timenow(), markerID); pthread_mutex_t marker= PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&marker); // lock local mutex for (job=0; job<N; job++) { addAvailableMarker(&marker,markerID); // marker is available while(!TIMEOUT) // While TIMEOUT hasn't occured yet wait to be grabbed pthread_cond_wait(&(COND[markerID]),&marker); // WAIT UNTIL GETTING GRABBED if (TIMEOUT) break; // If a TIMEOUT occurs then exit studentID = MAPPINGS[markerID]; printf("%d marker %d: grabbed by student %d (job %d)\n", timenow(), markerID, studentID, job+1); pthread_cond_signal(&(COND[markerID])); // Signal the student thread to start the presentation pthread_cond_wait(&(COND[markerID]),&marker); // Wait for the student thread to finish the presentation printf("%d marker %d: finished with student %d (job %d)\n", timenow(), markerID, studentID, job+1); } pthread_mutex_unlock(&marker); // Unlock local mutex if (job == N) { printf("%d marker %d: exits lab (finished %d jobs)\n", timenow(), markerID, N); } else { printf("%d marker %d: exits lab (timeout)\n", timenow(), markerID); } return NULL; } // student(arg): student thread void *student(void *arg) { int studentID = *(int *)arg; printf("%d student %d: starts panicking\n", timenow(), studentID); panic(); printf("%d student %d: enters lab\n", timenow(), studentID); /* printf("Student %d : S=%d M=%d K=%d N=%d T=%d D=%d\n",studentID , S, M, K, N, T, D);*/ markers mrks[K]; if(getMarkers(studentID,mrks)) // Get markers [Return 0 if TIMEOUT 1 if the required markers have been grabbed] lockMarkers(mrks,studentID); // Lock markers if (TIMEOUT) { // CHANGE 0 TO REAL CONDITION printf("%d student %d: exits lab (timeout)\n", timenow(), studentID); } else { printf("%d student %d: starts demo\n", timenow(), studentID); demo(); printf("%d student %d: ends demo\n", timenow(), studentID); printf("%d student %d: exits lab (finished)\n", timenow(), studentID); unlockMarkers(mrks); } return NULL; } int main(int argc, char *argv[]) { if (argc < 6) { printf("Usage: demo S M K N T D\n"); exit(1); } S = atoi(argv[1]); M = atoi(argv[2]); K = atoi(argv[3]); N = atoi(argv[4]); T = atoi(argv[5]); D = atoi(argv[6]); printf("S=%d M=%d K=%d N=%d T=%d D=%d\n", S, M, K, N, T, D); int i; int markerID[M], studentID[s]; pthread_t markerT[M], studentT[s]; // Initialize arrays AM = malloc(M * sizeof(markers)); COND = malloc(M * sizeof *COND); for(i=0; i<M; i++) pthread_cond_init(&(COND[i]),NULL); gettimeofday(&starttime, NULL); // Save start of simulated time // Create S student threads for (i=0; i<S; i++) { studentID[i] = i; pthread_create(&studentT[i], NULL, student, &studentID[i]); } // Create M marker threads for (i=0; i<M; i++) { markerID[i] = i; pthread_create(&markerT[i], NULL, marker, &markerID[i]); } delay(T-D); // Wait until latest time demo can start // MIGHT DO SOMETHING AT THIS TIME // Wait for student threads to finish for (i=0; i<S; i++) { pthread_join(studentT[i], NULL); } // Wait for marker threads to finish for (i=0; i<M; i++) { pthread_join(markerT[i], NULL); } return 0; }
Timonkaipumpa Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Όπως το έχεις δηλώσει και όπως περνάς το όρισμα είναι λογικό να μην δουλέψει. Εάν θέλεις να περνάς έναν πίνακα από markers στην getmarkers, και να αλλάζει η τιμή του κάθε marker, θα πρέπει να έχεις δείκτη σε δείκτη.
computeras13 Δημοσ. 11 Φεβρουαρίου 2012 Μέλος Δημοσ. 11 Φεβρουαρίου 2012 Thanks. Έκανα κάποιες αλλαγές που με βόλεψαν καλύτερα και το διόρθωσα. Πλέον τρέχει μια χαρά. Ευχαριστώ για το hint
Timonkaipumpa Δημοσ. 11 Φεβρουαρίου 2012 Δημοσ. 11 Φεβρουαρίου 2012 Thanks. Έκανα κάποιες αλλαγές που με βόλεψαν καλύτερα και το διόρθωσα. Πλέον τρέχει μια χαρά. Ευχαριστώ για το hint Ωρέ! Ωρέ ωρέ....!!! Don't mention it! Μακάρι όλες οι απορίες να ήταν σε τέτοια φάση όπως η δικιά σου. anytime m8.
albdum Δημοσ. 25 Φεβρουαρίου 2014 Δημοσ. 25 Φεβρουαρίου 2014 Φίλε μου καλησπέρα! Έχω και εγώ την ίδια εργασία για τον Gregory . Μήπως θα μπορούσες να μου στείλεις τις διορθώσεις που έκανες γιατί παλεύω και δεν βγάζω ακρή... Ούτε με τον δικό μου κώδικα ούτε με τον δικό σου
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα