[領卓教育]執行緒的同步與互斥機制——訊號量
阿新 • • 發佈:2018-10-31
訊號量的初始化
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能: 初始化訊號量
引數:
sem :要是初始化的訊號量
pshared: 訊號量共享的範圍(0: 執行緒間使用 非0:程序間使用)
value : 初始化的值
返回值:
成功0
失敗-1
訊號量的P操作與V操作
P:申請資源 sem_wait(sem_t * sem)
V:釋放資源 sem_post(sem_t * sem)
1.互斥
多個執行緒之間有共享資源(shared resource)時會出現互斥現象。
設有若干執行緒共享某個變數,而且都對變數有修改。如果它們之間不考慮相互協調工作,就會產生混亂。
例:只使用一個訊號量的執行緒互斥
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <semaphore.h> #define N 100 char buf[N] ; sem_t sem; void * pthread1_handler(void * data) { printf("value = %d\n",*(int *)data); while(1) { sem_wait(&sem); memset(buf,'O',N-1); buf[N-1] = '\0'; sem_post(&sem); usleep(1000); } } void * pthread2_handler(void * data) { printf("value = %d\n",*(int *)data); while(1) { sem_wait(&sem); memset(buf,'-',N-1); buf[N-1] = '\0'; sem_post(&sem); usleep(1000); } } void * pthread3_handler(void * data) { printf("value = %d\n",*(int *)data); while(1) { sem_wait(&sem); printf("%s\n",buf); sem_post(&sem); usleep(100000); } } int main(int argc, char * argv[]) { pthread_t tid1,tid2,tid3; int value1 = 100; int value2 = 200; int value3 = 300; int ret ; sem_init(&sem,0,1); ret = pthread_create(&tid1,NULL,pthread1_handler,&value1); if(ret != 0) { perror("pthread_create"); exit(-1); } ret = pthread_create(&tid2,NULL,pthread2_handler,&value2); if(ret != 0) { perror("pthread_create"); exit(-1); } ret = pthread_create(&tid3,NULL,pthread3_handler,&value3); if(ret != 0) { perror("pthread_create"); exit(-1); } while(1) { sleep(1); } return 0; }
執行結果:
buf = OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO buf = --------------------------------------------------------------------------------------------------- buf = OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO buf = OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO buf = OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO buf = --------------------------------------------------------------------------------------------------- buf = --------------------------------------------------------------------------------------------------- buf = OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO buf = ---------------------------------------------------------------------------------------------------
2.同步
指多個任務(執行緒)按照約定順序協調完成一件事情。
例:主執行緒和執行緒3負責列印字元,執行緒1和執行緒2負責寫入字元。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define N 128
char buf[N] = {0} ;
sem_t sem_w1;
sem_t sem_r1;
sem_t sem_w2;
sem_t sem_r2;
void * pthread1_handler(void * val)
{
while(1)
{
sem_wait(&sem_w1);
memset(buf,'O',N);
buf[N-1] = '\0';
sem_post(&sem_r1);
}
}
void * pthread2_handler(void * val)
{
while(1)
{
sem_wait(&sem_w2);
memset(buf,'-',N);
buf[N-1] = '\0';
sem_post(&sem_r2);
}
}
void * pthread3_handler(void * val)
{
while(1)
{
sem_wait(&sem_r2);
printf("buf= %s\n",buf);
sleep(1);
sem_post(&sem_w1);
}
}
int main(int argc, const char *argv[])
{
pthread_t tid1;
pthread_t tid2;
pthread_t tid3;
int value1 = 100 ;
int value2 = 200 ;
int value3 = 300 ;
int ret ;
sem_init(&sem_r1,0,1);
sem_init(&sem_w1,0,0);
sem_init(&sem_r2,0,0);
sem_init(&sem_w2,0,0);
ret = pthread_create(&tid1,NULL,pthread1_handler,&value1) ;
if(ret != 0)
{
perror("pthread1_create");
exit(-1);
}
ret = pthread_create(&tid2,NULL,pthread2_handler,&value2) ;
if(ret != 0)
{
perror("pthread2_create");
exit(-1);
}
ret = pthread_create(&tid3,NULL,pthread3_handler,&value3) ;
if(ret != 0)
{
perror("pthread3_create");
exit(-1);
}
while(1)
{
sem_wait(&sem_r1);
printf("buf= %s\n",buf);
sleep(1);
sem_post(&sem_w2);
}
return 0;
}
執行結果:
buf= -------------------------------------------------------------------------------------------------------------------------------
buf= OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
buf= -------------------------------------------------------------------------------------------------------------------------------
buf= OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
buf= -------------------------------------------------------------------------------------------------------------------------------
buf= OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
buf= -------------------------------------------------------------------------------------------------------------------------------
應用訊號量實現執行緒同步:
訊號量初始化時先使能一個訊號量,方便控制其他訊號量以實現執行緒的同步。