linux多线程总结

//testThreadRingBuffer
//author: lxk
//date: 2019-04-11
#include <stdio.h>
#include <pthread.h>

#define BUFFER_SIZE 16    // 缓冲区数量
#define TEST_DATA_NUM 200  //测试数据数量
#define TEST_OVER -1    //测试结束标志
#define MY_SUCCESS 0    //成功
#define MY_ERROR 1        //失败

typedef struct testThreadRingBuffer_t
{
    // 缓冲区相关数据结构
    int nRingBuffer[BUFFER_SIZE]; /* 实际数据存放的数组*/
    pthread_mutex_t mutex_lock; /* 互斥体lock 用于对缓冲区的互斥操作 */
    int nReadPos;    /* 读指针位置 */
    int nWritePos;  /* 写指针位置 */
    pthread_cond_t notEmptyFlag; /* 缓冲区非空的条件变量 */
    pthread_cond_t notFullFlag; /* 缓冲区未满的条件变量 */
}testThreadRingBuffer_t;

testThreadRingBuffer_t g_ThreadRingBuffer;

/* 初始化缓冲区结构 */
void test_thread_ring_buffer_init(testThreadRingBuffer_t *args)
{
    pthread_mutex_init(&args->mutex_lock, NULL);
    pthread_cond_init(&args->notEmptyFlag, NULL);
    pthread_cond_init(&args->notFullFlag, NULL);
    args->nReadPos = 0;
    args->nWritePos = 0;
}

/* 缓冲区已满 */
int ring_buffer_is_full(testThreadRingBuffer_t *args)
{
    int ret;
    ret = ((args->nWritePos + 1) % BUFFER_SIZE == args->nReadPos);
    return ret;
    //return ((args->nWritePos + 1) % BUFFER_SIZE == args->nReadPos);
}

/* 缓冲区已空 */
int ring_buffer_is_empty(testThreadRingBuffer_t *args)
{
    int ret;
    ret = args->nWritePos == args->nReadPos;
    return ret;
    //return (args->nWritePos == args->nReadPos);
}

/* 将DATA放入缓冲区,这里是存入一个整数 */
void put_data_to_thread_ring_buffer(testThreadRingBuffer_t *args, int nData)
{
    pthread_mutex_lock(&args->mutex_lock);
    /* 等待缓冲区未满 */
    if (ring_buffer_is_full(args)) //判定缓冲区已满
    {
        pthread_cond_wait(&args->notFullFlag, &args->mutex_lock);
    }
    /* 写数据,并移动指针 */
    args->nRingBuffer[args->nWritePos] = nData;
    args->nWritePos++;
    /* 如果写到尽头 */
    if (args->nWritePos >= BUFFER_SIZE)
        args->nWritePos = 0;
    /* 设置缓冲区非空的条件变量 */
    pthread_cond_signal(&args->notEmptyFlag);  //给一个已有数据信号 可以继续读取
    pthread_mutex_unlock(&args->mutex_lock);
}

/* 从缓冲区中取出DATA */
int get_data_from_thread_ring_buffer(testThreadRingBuffer_t *args)
{
    int nTempData;
    pthread_mutex_lock(&args->mutex_lock);
    /* 等待缓冲区非空 */
    if (ring_buffer_is_empty(args))
    {
        pthread_cond_wait(&args->notEmptyFlag, &args->mutex_lock);
    }
    /* 读数据,移动读指针 */
    nTempData = args->nRingBuffer[args->nReadPos];
    args->nReadPos++;
    /* 如果读到尽头 */
    if (args->nReadPos >= BUFFER_SIZE)
        args->nReadPos = 0;
    /* 设置缓冲区未满的条件变量 */
    pthread_cond_signal(&args->notFullFlag);  //给一个数据信号 数据已经被消耗 可以继续传数据
    pthread_mutex_unlock(&args->mutex_lock);
    return nTempData;
}

/* 测试:生产者线程将0 到TEST_DATA_NUM 的整数送入缓冲区,消费者线
程从缓冲区中获取整数,两者都打印信息 */
void* producer_thread(void *data)
{
    int i;
    printf("producer_thread start\n");
    for (i = 0; i <= TEST_DATA_NUM; i++)
    {
        printf("PUT %d to ringBuffer\n", i);
        put_data_to_thread_ring_buffer(&g_ThreadRingBuffer, i);
    } 
    put_data_to_thread_ring_buffer(&g_ThreadRingBuffer, TEST_OVER);
    printf("producer_thread leave\n");
    pthread_exit(0);
    return MY_SUCCESS;
}

void* consumer_thread(void *data)
{
    int n_TempData;
    printf("consumer_thread start\n");
    while (1)
    {
        n_TempData = get_data_from_thread_ring_buffer(&g_ThreadRingBuffer);
        if (n_TempData == TEST_OVER)
            break;
        printf("GET %d from ringBuffer \n", n_TempData);
    }
    printf("consumer_thread leave\n");
    pthread_exit(0);
    return MY_SUCCESS;
}

int main(void)
{
    int ret;
    pthread_t threadID_A, threadID_B;
    test_thread_ring_buffer_init(&g_ThreadRingBuffer);
    /* 创建生产者和消费者线程 */
    ret = pthread_create(&threadID_A, NULL, producer_thread, 0);
    if (ret)
    {
        printf("create producer_thread ERROR\n");
        return MY_ERROR;
    }
    ret = pthread_create(&threadID_B, NULL, consumer_thread, 0);
    if (ret)
    {
        printf("create producer_thread ERROR\n");
        return MY_ERROR;
    }
    /* 等待两个线程结束 */
    pthread_join(threadID_A, NULL);
    pthread_join(threadID_B, NULL);
    printf("\ninput any character to exit\n");
    getchar();
    return MY_SUCCESS;
}

猜你喜欢

转载自www.cnblogs.com/Lxk0825/p/10689835.html