线程安全之信号量

2022-10-07  本文已影响0人  二进制人类

相关API

初始化信号量

#include <semaphore.h>
/**
 * [sem_init 初始信号量]
 * @param  sem     [初始化信号量的指针]
 * @param  pshared [
 * pshared表示信号量访问可见性:
        0 表示的当前进程中的多个线程可见(推荐)
        非0 表示可以多个进程间可见;
 * ]
 * @param  value   [表示的信号量的初始值]
 * @return         [成功返回0,失败返回-1且修改errno的值]
 */
int sem_init(sem_t *sem, int pshared, unsigned int value);

销毁

#include <semaphore.h>
int sem_destroy(sem_t *sem);

p操作

#include <semaphore.h>
/*功能:P操作,阻塞模式实现,当信号量的值等于0进入阻塞态,直到信号量大于0唤醒并sem--;*/
int sem_wait(sem_t *sem);
/*功能:以非阻塞模式实现,当信号量的等于0直接返回错误信息,大于0sem--;*/
int sem_trywait(sem_t *sem);
/*功能:在设定的时间范围内阻塞,信号量大于0sem--或者超过时间直接返回,*/
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

v操作

#include <semaphore.h>
int sem_post(sem_t *sem);    //sem++;

互斥实现

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem;/* 定义信号量 */
char buf[] = "0123456789";

/* 定义数组元素输出子线程执行函数 */
void *prt_arr(void *arg)
{
    while(1)
    {
        /* P操作 */
        sem_wait(&sem);
        printf("%s\n", buf);
        /* V操作 */
        sem_post(&sem);
        sleep(1);
    }
}

/* 定义数组元素倒序子线程执行函数 */
void *reverse_arr(void *arg)
{
    int i;
    char tmp;
    while(1)
    {
        /* P操作 */
        sem_wait(&sem);
        for (i = 0; i < 5; i++)
        {
            tmp = buf[i];
            buf[i] = buf[9 - i];
            buf[9 - i] = tmp;
        }
        /* V操作 */
        sem_post(&sem);
    }
}

int main()
{
    int ret;
    pthread_t prt_id;
    pthread_t reverse_id;
    /* 初始化信号量的值为1 */
    sem_init(&sem, 0, 1);
    ret = pthread_create(&prt_id, NULL, prt_arr, NULL);
    if (ret != 0)
    {
        fprintf(stderr, "create video pthread fail\n");
        return -1;
    }
    ret = pthread_create(&reverse_id, NULL, reverse_arr, NULL);
    if (ret != 0)
    {
        fprintf(stderr, "create video pthread fail\n");
        return -1;
    }
    while(1)
    {
        printf("main pthread\n");
        sleep(10);
    }
    /* 销毁信号量 */
    sem_destroy(&sem);
}

同步实现

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem;/* 定义信号量 */
sem_t sem1;
char buf[] = "0123456789";

/* 定义数组元素输出子线程执行函数:消费者线程 */
void *prt_arr(void *arg)
{
    while(1)
    {
        /* P操作 */
        sem_wait(&sem);
        sleep(1);
        printf("%s\n", buf);
        sem_post(&sem1);
    }
}

/* 定义数组元素倒序子线程执行函数:生产者线程 */
void *reverse_arr(void *arg)
{
    int i;
    char tmp;
    while(1)
    {
        /* P操作sem1 */
        sem_wait(&sem1);
        for (i = 0; i < 5; i++)
        {
            tmp = buf[i];
            buf[i] = buf[9 - i];
            buf[9 - i] = tmp;
        }
        //sleep(1);
        /* V操作 */
        printf("------------------\n");
        sem_post(&sem);
    }
}

int main()
{
    int ret;
    pthread_t prt_id;
    pthread_t reverse_id;
    /* 初始化信号量的值为0 */
    sem_init(&sem, 0, 0);
    sem_init(&sem1, 0, 1);
    ret = pthread_create(&prt_id, NULL, prt_arr, NULL);
    if (ret != 0)
    {
        fprintf(stderr, "create video pthread fail\n");
        return -1;
    }
    ret = pthread_create(&reverse_id, NULL, reverse_arr, NULL);
    if (ret != 0)
    {
        fprintf(stderr, "create video pthread fail\n");
        return -1;
    }
    while(1)
    {
        printf("main pthread\n");
        sleep(10);
    }
    /* 销毁信号量 */
    sem_destroy(&sem);
    sem_destroy(&sem1);
}
上一篇下一篇

猜你喜欢

热点阅读