HI It is working for me... (SUSE 9.0, gcc (GCC) 3.3.1 (SuSE Linux)) I always get 5 ships in the port. Look at the start of the program five ships enters to the port and five are blocked. Zsolt praisetazio wrote:
The following code should simulate a port with M places and N ships accessing to it. The problem: in the "entering_request" function, the program controls how many ships are in port, if there are too many ships the program should block on a condition variable. The problem is that it does not work, and I usually get more than M ships at runtime. I think that I am misunderstanding something, anybody could enlighten me?
#include
#include #include #include #define N 10 #define M 5
struct port { pthread_mutex_t mutex; pthread_cond_t full; int ships; int waiting; } Port = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 };
void* ship (void* arg);
int main() { void* nothing; pthread_t ships[N]; int i; pthread_setconcurrency(N); for (i=0; i
void entering_request() { pthread_mutex_lock(&Port.mutex); if (Port.ships>=M) { Port.waiting++; printf("ship %d blocked\n", pthread_self()); pthread_cond_wait(&Port.full, &Port.mutex); printf("ship %d unblocked\n", pthread_self()); Port.waiting--; } }
void entering() { printf ("ship %d enters the port", pthread_self()); printf ("\n%d ships in port\n", Port.ships); }
void leaving_entrance() { Port.ships++; printf("Ships inside the port: %d\n", Port.ships); pthread_mutex_unlock(&Port.mutex); }
void stationing () { int l, i; srand(time(NULL)); printf("La ship %d is inside with other %d ships.\n", pthread_self(), Port.ships); l = rand(); /* Wasting time */ for (i=0; i
void exit_request() { pthread_mutex_lock(&Port.mutex); }
void exiting() { printf ("ship %d out of the port\n", pthread_self()); printf ("%d ships\n remain in port", Port.ships); }
void leaving_exit() { Port.ships--; if (Port.waiting) pthread_cond_signal (&Port.full); pthread_mutex_unlock(&Port.mutex); }
void* ship (void* arg) { int i; for (i=0; i<3000; i++) { entering_request(); entering(); leaving_entrance(); stationing(); exit_request(); exiting(); leaving_exit(); } return NULL; }