Witam,
Chciałbym poruszyć klasyczny: "Problem producentów i konsumentów" - jedna grupa procesów produkuje dane, druga grupa je
konsumuje – jak zagwarantować sprawny (bez zakleszczeń i zagłodzeń) przebieg tej procedury czy w tym wypadku. W tym przypadku jednak będzie to "Problem czytelników i pisarzy".
plik1.c
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include"czytelnia.h"
/*** Implementacja procedur interfejsu ***/
int my_read_lock_lock(czytelnia_t* czytelnia_p){
//pthread_mutex_lock (&muteks);
}
int my_read_lock_unlock(czytelnia_t* czytelnia_p){
//pthread_mutex_unlock( &muteks );
int my_write_lock_lock(czytelnia_t* czytelnia_p){
//pthread_mutex_lock (&muteks );
}
int my_write_lock_unlock(czytelnia_t* czytelnia_p){
//pthread_mutex_unlock( &muteks );
}
void inicjuj(czytelnia_t* czytelnia_p){
//?????
}
void czytam(czytelnia_t* czytelnia_p){
usleep(1000000);
}
void pisze(czytelnia_t* czytelnia_p){
usleep(1000000);
}
///plik2.c
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include"czytelnia.h"
void *funkcja_czytelnika( void *);
void *funkcja_pisarza( void *);
int liczba_czytlnik = 6;
int liczba_pisarzy = 3;
int main(){
if(liczba_czytlnik || liczba_pisarzy)
{
return 0;
}
int i;
pthread_t pisarze[liczba_pisarzy], czytelnicy[liczba_czytlnik]; //pisar->5, czyt -> 10
int indeksy[10] = {0,1,2,3,4,5,6,7,8,9};
czytelnia_t czytelnia;
inicjuj(&czytelnia);
for(i=0; i<liczba_pisarzy; i++){
pthread_create( &pisarze[i], NULL, funkcja_pisarza, (void *)&czytelnia );
}
for(i=0; i<liczba_czytlnik; i++){
pthread_create( &czytelnicy[i], NULL, funkcja_czytelnika, (void *)&czytelnia );
}
for(i=0; i<liczba_pisarzy; i++){
pthread_join( pisarze[i], NULL);
}
for(i=0; i<liczba_czytlnik; i++){
pthread_join( czytelnicy[i], NULL );
}
}
void *funkcja_czytelnika( void * arg){
czytelnia_t* czytelnia_p = (czytelnia_t *)arg;
for(;;){
usleep(1000000);
printf("czytelnik %d - przed zamkiem\n", pthread_self());
my_read_lock_lock(czytelnia_p);
// korzystanie z zasobow czytelni
printf("czytelnik %d - wchodze\n", pthread_self());
czytam(czytelnia_p);
printf("czytelnik %d - wychodze\n", pthread_self());
my_read_lock_unlock(czytelnia_p);
printf("czytelnik %d - po zamku\n", pthread_self());
}
slo
}
void *funkcja_pisarza( void * arg){
czytelnia_t* czytelnia_p = (czytelnia_t *)arg;
for(;;){
usleep(1000000);
printf("pisarz %d - przed zamkiem\n", pthread_self());
my_write_lock_lock(czytelnia_p);
// korzystanie z zasobow czytelni
printf("pisarz %d - wchodze\n", pthread_self());
pisze(czytelnia_p);
printf("pisarz %d - wychodze\n", pthread_self());
my_write_lock_unlock(czytelnia_p);
printf("pisarz %d - po zamku\n", pthread_self());
}
}
// HEADER
#ifndef _czytelnia_
#define _czytelnia_
/*** Definicje typow zmiennych ***/
typedef struct {
// <- zasoby czytelni
} czytelnia_t;
/*** Deklaracje procedur interfejsu ***/
void inicjuj(czytelnia_t* czytelnia_p);
void czytam(czytelnia_t* czytelnia_p);
void pisze(czytelnia_t* czytelnia_p);
int my_read_lock_lock(czytelnia_t* czytelnia_p);
int my_read_lock_unlock(czytelnia_t* czytelnia_p);
int my_write_lock_lock(czytelnia_t* czytelnia_p);
int my_write_lock_unlock(czytelnia_t* czytelnia_p);
#endif
//////////
Gdyby był to 1 plik, można by było umieścić thready nad main'em i sb lock/unlockować.
Do wątku możemy przesłać jeden argument, myślałem nad wykorzystaniem struktury w Head i tam przenieś wątki.
Myślę ze również należy umieścić pthread_cond_signal, pthread_cond_wait tylko gdzie.
Czy to dobry pomysł? Jakas inna koncepcja? Nie wiem jak rozwiązać problem.
Bardzo prosze o pomoc, z góry dziękuję za każda inicjatywę.