sem_init

创建并初始化信号量

头文件:
    #include <semaphore.h>
原型:
    int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
    sem_t *sem:存储创建并初始化后的信号量;
    int pshared:共享标识,参数如下:
        0:用于线程;
        非0:用于进程;
    unsigned int value:信号量的初始值;
返回值:
    成功,返回0;
    失败,返回-1,更新errno;
例程:
    static sem_t sem;
    if(sem_init(&sem, 0, 3) < 0)
    {
        perror("sem_init");
        return -1;
    }
    printf("sem初始化成功\n");

sem_destroy

销毁信号量

头文件:
    #include <semaphore.h>
原型:
    int sem_destroy(sem_t *sem);
参数:
    set_t *sem:信号量标识;
返回值:
    成功,返回0;
    失败,返回-1,设置errno;
例程:
    if(sem_destroy(&sem))
    {
        perror("sem_destroy");
        return -1;
    }

sem_wait

申请信号量,P操作,-1

1.如果申请前,信号量为0,则该线程阻塞,进入休眠;
2.如果申请前,信号量大于0,则申请成功,信号量-1,函数立即返回;

头文件:
    #include <semaphore.h>
原型:
    int sem_wait(sem_t *sem);
参数:
    sem_t *sem:指定需要申请的信号量;
返回值:
    成功,返回0;
    失败,返回-1,设置errno;
例程:
    if(sem_wait(&sem) < 0) 
    {
        perror("sem_wait");
        return -1;
    }

sem_post

释放信号量,V操作,+1

头文件:
    #include <semaphore.h>
原型:
    int sem_post(sem_t *sem);
参数:
    sem_t *sem:指定信号量;
返回值:
    成功,返回0;
    失败,返回-1,更新errno;
例程:
    if(sem_post(&sem) < 0) 
    {
        perror("sem_post");
        return -1;
    }

sem_getvalue

获取指定信号量的值

头文件:
    #include <semaphore.h>
原型:
    int sem_getvalue(sem_t *sem, int *sval);
参数:
    sem_t *sem:指定信号量;
    int *sval:存储获取到的信号量的值;
返回值:
    成功,返回0;
    失败,返回-1,更新errno;
例程:
    int sval;
    sem_getvalue(&sem, &sval);
    printf("sval=%d line=%d\n", sval, __LINE__);

应用例程1

用信号量的方式实现一个线程倒置,一个线程打印,倒置一次打印一次

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
//临界资源(共享资源)
char str[30] = "AAAAAAAAAAA|BBBBBBBBBB";
sem_t sem1;
sem_t sem2;
//打印线程
void* handler1(void* arg)
{
    while(1)
    {
        /*******临界区******/
        sem_wait(&sem1);
        printf("%s\n", str);
        sem_post(&sem2);
        /*******临界区******/
    }
    pthread_exit(NULL);
}
//倒置线程
void* handler2(void* arg)
{
    char* start = NULL;
    char* end = NULL;
    char temp = 0;
    while(1)
    {
        start = str;
        end = str+strlen(str)-1;
        /*******临界区******/
        sem_wait(&sem2);
        while(start < end)
        {
            temp = *start;
            *start = *end;
            *end = temp;
            start++;
            end--;
        }
        sem_post(&sem1);
        /*******临界区******/
    }
    pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
    //sem1控制打印
    if(sem_init(&sem1, 0, 1) < 0)
    {
        perror("sem_init");
        return -1;
    }
    //sem2控制倒置
    if(sem_init(&sem2, 0, 0) < 0)
    {
        perror("sem_init");
        return -1;
    }
    pthread_t tid1, tid2;
    if(pthread_create(&tid1, NULL, handler1, NULL) != 0)
    {
        perror("pthread_create");
        return -1;
    }
    if(pthread_create(&tid2, NULL, handler2, NULL) != 0)
    {
        perror("pthread_create");
        return -1;
    }
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    //销毁信号量
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    return 0;
}

应用例程2

创建两个线程,实现

  1. 将一个文档的内容打印到终端上。类似 cat一个文件。
  2. 打印完毕后,退出进程。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
//共享资源
FILE *fp = NULL;
char c = 0;
//信号量
sem_t sem_r,sem_w;
//线程1,读数据
void *handler1(void *arg)
{
    while(1)
    {
        sem_wait(&sem_r);
        c = fgetc(fp);
        fflush(fp);
        if(c == EOF)
        {
            printf("线程1-->读取完毕\n");
            sem_post(&sem_w);
            break;
        }
        sem_post(&sem_w);
    }
    pthread_exit(NULL);
}
//线程2,写数据-->打印到终端上
void *handler2(void *arg)
{
    while(1)
    {
        sem_wait(&sem_w);
        if(c == EOF)
        {
            printf("线程2-->打印完毕\n");
            break;
        }
        fputc(c,stdout);
        fflush(fp);
        sem_post(&sem_r);
    }
    pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
    fp = fopen("./cat.c","r");
    if(sem_init(&sem_r,0,1) < 0)
    {
        perror("sem_init_r");
        return -1;
    }
    if(sem_init(&sem_w,0,0) < 0)
    {
        perror("sem_init_w");
        return -1;
    }
    pthread_t tid1,tid2;
    if(pthread_create(&tid1,NULL,handler1,NULL)!=0)
    {
        perror("pthread_create_tid1");
        return -1;
    }
    if(pthread_create(&tid2,NULL,handler2,NULL)!=0)
    {
        perror("pthread_create_tid2");
        return -1;
    }
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    //销毁信号量
    sem_destroy(&sem_r);
    sem_destroy(&sem_w);
    return 0;
}

结果

Last modification:2021 年 04 月 08 日 18 : 34 : 27