When thread process the variable. There are three steps:bash
If multiple thread is executing same variable at the same time, there might be a critical section.ide
We can use pthread_mutex_lock() to avoid the critical section.oop
pthread_mutex_t *lock = malloc(sizeof(pthread_mutex_t);
pthread_mutex_init(lock,NULL);
//same as pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER
pthread_mutex_lock(lock);
pthread_mutex_unlock(lock);
pthread_mutex_destroy(lock);
free(lock);
複製代碼
Pthread_mutex_lock won't stop other threads, other threads will have to wait when they are trying to lock the same lock until the mutex is unlocked. If a mutex was locked, it can't be unlock by another thread.post
sem_t s;
sem_init(&s, 0, 10);
sem_wait(&s);
sem_post(&s);
sem_destroy(&s);
複製代碼
Thread Safe Push:ui
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int count = 0;
double values[10];
sem_t sitems, sremain;
void init(){
sem_init(&sitems, 0, 0);
sem_init(&sremains, 0, 10);
}
double pop(){
sem_wait(&sitems);
pthread_mutex_lock(&m);
double result = values[--count];
pthread_mutex_unlock(&m);
sem_post(&sremains);
return result;
}
void push(double v){
sem_wait(&sremains);
pthread_mutex_lock(&m);
values[count++] = v;
pthread_mutex_unlock(&m);
sem_post(&sitems);
}
}
複製代碼
raise my flag
turn = your_id
wait while your flag is raised and turn is your_id
//Do critical Section
lower my flag
複製代碼
It allow threads sleep until tickled. We can use pthread_cond_signal() to wake up one thread (System decide which one to wake up) or all threads with pthread_cond_broadcast(). There will be a spurious wake of waiting thread.spa
define struct sem_t{
int count;
pthread_mutex_t m;
pthread_cond_t cv;
} sem_t
int sem_init(sem_t *s, int pshared, int value){
if(pshared){errno = ENOSYS;return -1;}
s->count = 0;
pthread_mutex_init(s->&m, NULL);
pthread_cond_init(s->&cv, NULL);
return 0;
}
void sem_wait(sem_t *s){
pthread_mutex_lock(s->&m);
while(s->count == 0){
pthread_cond_wait(&cv,&m);
}
s->count--;
pthread_mutex_unlock(s->&m);
}
void sem_signal(){
pthread_mutex_lock(s->&m);
count++;
pthread_cond_signal(s->&cv);
pthread_mutex_unlock(s->&m);
}
複製代碼
Barrier is used to wait N threads to reach a certain point before continuing onto next step. There is a function named pthread_barrier_wait(). We need to declare a pthread_barrier_t variable and initialize it with pthread_barrier_init().code
Write our own simple barrier:orm
pthread_mutex_lock(&m);
remain --;
if(remain == 0){
pthread_cond_broadcast(&cv);
}
while(remain > 0){
pthread_cond_wait(&cv,&m);
}
pthread_mutex_unlock(&m);
複製代碼
reader(){
lock(&m);
while(writer) pthread_cond_wait(&cv, &m);
read++
unlock(&m);
lock(&m)
read--;
pthread_cond_broadcast(&cv);
unlock(&m);
}
writer(){
lock(&m);
writer++;
while(writer || reader) pthread_cond_wait(&cv,&m);
writer++;
unlock(&m);
lock(&m);
writer--;
writer--;
pthread_cond_broadcast(&cv);
unlock(&m);
}
複製代碼
circular wait: There exist a circle in Resource Allocation Graph. hold and wait: Thread will holding the current resource while waiting for the resource hold by others mutual exclusion: The resource can't be shared no-preemption: Resource can't be taken by others.three
Deadlockip