多线程+信号量同步线程

发布时间 2023-12-18 10:53:48作者: 蔡头一枚

实现场景: 多线程 + 信号量实现线程同步执行

线程在创建的时候并不能保证优先顺序,是异步的,如果想按照自己指定的顺序先后执行的话,可以使用一些互斥或者同步的方式; 以下我是通过信号量来实现同步:

信号量的类型是sem_t, 需要的头文件是 #include <semaphore.h>, 主要是方法是sem_init(), sem_wait(), sem_post(), sem_destroy(), 主要的原理是通过原子计数的方式实现同步, 测试代码如下:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <errno.h>

/**
*       实现场景: 多线程 + 线程同步执行
*/

// 信号量
sem_t   SEM_A_B;
sem_t   SEM_B_C;
sem_t   SEM_C_A;

// 函数指针
typedef void *fFunc(void *arg);

void *funcA(void *arg)
{
    (void)arg;
    pthread_detach(pthread_self());

    sem_wait(&SEM_C_A);
    sem_post(&SEM_A_B);

    printf("run func: %s | line: %d\n", __FUNCTION__, __LINE__);

    while (1)
    {
    }
    return NULL;
}

void *funcB(void *arg)

{
    (void)arg;
    pthread_detach(pthread_self());

    sem_wait(&SEM_A_B);
    sem_post(&SEM_B_C);     // 信号量+1

    printf("func: %s | line: %d\n", __FUNCTION__, __LINE__);
    while (1)
    {
    }
    return NULL;
}

void *funcC(void *arg)
{
    (void)arg;
    pthread_detach(pthread_self());

    sem_wait(&SEM_B_C);     // 信号量-1,为0接触阻塞, 大于0程序往下执行
    sem_post(&SEM_C_A);

    printf("func: %s | line: %d\n", __FUNCTION__, __LINE__);
    while (1)
    {
    }
    return NULL;
}


int main(void)
{
    // 初始化信号量
    sem_init(&SEM_A_B, 0, 0);
    sem_init(&SEM_B_C, 0, 0);
    sem_init(&SEM_C_A, 0, 1);       // 初始化信号量的值为1,表示表示该可以进行自减一操作,直接跳过阻塞

    // 初始化函数指针
    fFunc *pFunc;

    pthread_t Thread_A;
    pthread_t Thread_B;
    pthread_t Thread_C;

    pFunc = funcA;
    printf("pFunc: %p\n", pFunc);
    if ( 0 != pthread_create(&Thread_A, NULL ,pFunc, NULL) )
    {
        printf("error: %s\n", strerror(errno));
    }

    pFunc = funcB;
    printf("pFunc: %p\n", pFunc);
    if ( 0 != pthread_create(&Thread_B, NULL ,pFunc, NULL) )
    {
        printf("error: %s\n", strerror(errno));
    }

    pFunc = funcC;
    printf("pFunc: %p\n", pFunc);
    if ( 0 != pthread_create(&Thread_C, NULL ,pFunc, NULL) )
    {
        printf("error: %s\n", strerror(errno));
    }

    pthread_join(Thread_A, NULL);
    pthread_join(Thread_B, NULL);
    pthread_join(Thread_C, NULL);

    sem_destroy(&SEM_A_B);
    sem_destroy(&SEM_B_C);
    sem_destroy(&SEM_C_A);
    return 0;
}