Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα σε όλους. Προσπαθώ να γράψω ένα πρόγραμμα (μια εργασία για την ακρίβεια) που έχει να κάνει με 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;
}

Δημοσ.

Όπως το έχεις δηλώσει και όπως περνάς το όρισμα είναι λογικό να μην δουλέψει.

 

 

Εάν θέλεις να περνάς έναν πίνακα από markers στην getmarkers, και να αλλάζει η τιμή του κάθε marker, θα πρέπει να έχεις δείκτη σε δείκτη.

Δημοσ.

Thanks. Έκανα κάποιες αλλαγές που με βόλεψαν καλύτερα και το διόρθωσα. Πλέον τρέχει μια χαρά. Ευχαριστώ για το hint :)

 

 

Ωρέ! Ωρέ ωρέ....!!!

 

 

 

 

 

Don't mention it!

 

 

Μακάρι όλες οι απορίες να ήταν σε τέτοια φάση όπως η δικιά σου. :)

 

 

anytime m8.

  • 2 χρόνια αργότερα...
Δημοσ.

Φίλε μου καλησπέρα! Έχω και εγώ την ίδια εργασία για τον Gregory :). Μήπως θα μπορούσες να μου στείλεις τις διορθώσεις που έκανες γιατί παλεύω και δεν βγάζω ακρή... Ούτε με τον δικό μου κώδικα ούτε με τον δικό σου :)

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...