[领卓教育]线程的同步与互斥机制——信号量

信号量的初始化
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= -------------------------------------------------------------------------------------------------------------------------------

应用信号量实现线程同步:

信号量初始化时先使能一个信号量,方便控制其他信号量以实现线程的同步。

猜你喜欢

转载自blog.csdn.net/a1421604395/article/details/83548104
今日推荐