François Trahay
Content of this lecture
int pipe(int pipefd[2]);
pipefd[0]
for reading, pipefd[1]
for
writingint mkfifo(const char *pathname, mode_t mode);
lseek
is impossibleint shm_open(const char *name, int oflag, mode_t mode);
name
is a key of the form /key
int ftruncate(int fd, off_t length);
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
flags
must contain MAP_SHARED
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
name
is a key of the form /key
int sem_init(sem_t *sem, int pshared, unsigned int value);
pshared != 0
, ca be used by several processes (using
a shared memory segment)int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
int sem_post(sem_t *sem);
pthread_mutex_t
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(ptread_mutex_t *m, const pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex));
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *restrict attr, unsigned count);
int pthread_barrier_wait(pthread_barrier_t *barrier);
count
threads reach
pthread_barrier_wait
count
threadspthread_rwlock_t
int pthread_rwlock_rdlock(pthread_rwlock_t* lock)
int pthread_rwlock_wrlock(pthread_rwlock_t* lock)
int pthread_rwlock_unlock(pthread_rwlock_t* lock)
m
initializedmutex_lock(m)
at the start of the critical
sectionmutex_unlock(m)
at the end of the critical
sectionm
initializedN
, and a monitor
m
to protect the counter Prog Vehicule
...
mutex_lock(m);
while(cpt == 0){ cond_wait(m); }
cpt--;
mutex_unlock(m);
|...
mutex_lock(m);
cpt++;
cond_signal(m);
mutex_unlock(m);
N
blocks buffer
Produc
: produces info0
Produc
: produces info1
Conso
: consumes info0
Produc
: produces info2
available_spots
monitor initialized to
N
ready_info
monitor initialized to 0
Producer: Consumer:
repeat repeat
... ...
mutex_lock(available_spots); mutex_lock(ready_info);
while(available_spots<=0) while(ready_info<=0)
cond_wait(available_spots); cond_wait(ready_info);
reserve_slot(); extract(info)
mutex_unlock(available_spots); mutex_unlock(ready_info);
calcul(info) mutex_lock(available_spots);
free_slot();
mutex_lock(ready_info); cond_signal(available_spots)
push(info); mutex_unlock(available_spots);
cond_signal(ready_info);
mutex_unlock(ready_info); ...
... endRepeat
endRepeat
It is of course possible to implement a producer / consumer scheme between processes using conditions and mutexes. Another simpler solution is to use a pipe: since writing in a pipe being atomic, the deposit of a data boils down to writing into the pipe, and reading from the pipe extracts the data.
pthread_rwlock_t
int pthread_rwlock_rdlock(pthread_rwlock_t* lock)
to
protect read operationsint pthread_rwlock_wrlock(pthread_rwlock_t* lock)
to
protect write operationsint pthread_rwlock_unlock(pthread_rwlock_t* lock)
to
release the lock