linux c 字符串环形buf (一)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>


#define BUFFER_SIZE 25


pthread_mutex_t rand_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t prod_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t cons_cond = PTHREAD_COND_INITIALIZER;


typedef struct {
    char *buffer;
    size_t capacity;
    size_t read_index;
    size_t write_index;
    pthread_mutex_t mutex;
} CircularBuffer;

CircularBuffer cb;

void cb_init(CircularBuffer *cb, size_t capacity) 
{
    cb->buffer = (char*)malloc(capacity);
    if (cb->buffer == NULL) {
        perror("malloc rand pool");
        exit(EXIT_FAILURE);
    }
    cb->capacity = capacity;
    cb->read_index = 0;
    cb->write_index = 0;
    pthread_mutex_init(&cb->mutex, NULL);
}

void cb_destroy(CircularBuffer *cb) 
{
    if (cb->buffer)
        free(cb->buffer);

    cb->buffer = NULL;
    pthread_mutex_destroy(&cb->mutex);
}

int cb_write(CircularBuffer *cb, const char *data, size_t len) 
{
    pthread_mutex_lock(&cb->mutex);
    size_t free_space = (cb->read_index + cb->capacity - cb->write_index - 1) % cb->capacity;
    if (free_space <= 0) {
        pthread_mutex_unlock(&cb->mutex);
        return -1;
    }

    len = len < free_space ? len : free_space;

    size_t part1 = cb->capacity - cb->write_index;
    if (part1 >= len) {
        memcpy(cb->buffer + cb->write_index, data, len);
    } else {
        memcpy(cb->buffer + cb->write_index, data, part1);
        memcpy(cb->buffer, data + part1, len - part1);
    }
    cb->write_index = (cb->write_index + len) % cb->capacity;

    pthread_mutex_unlock(&cb->mutex);
    return len;
}

int cb_read(CircularBuffer *cb, char *data, size_t len) 
{
    pthread_mutex_lock(&cb->mutex);
    size_t available_data = (cb->write_index + cb->capacity - cb->read_index) % cb->capacity;
    if (available_data < len) {
        pthread_mutex_unlock(&cb->mutex);
        return -1;
    }

    size_t part1 = cb->capacity - cb->read_index;
    if (part1 >= len) {
        memcpy(data, cb->buffer + cb->read_index, len);
    } else {
        memcpy(data, cb->buffer + cb->read_index, part1);
        memcpy(data + part1, cb->buffer, len - part1);
    }
    cb->read_index = (cb->read_index + len) % cb->capacity;

    pthread_mutex_unlock(&cb->mutex);
    return len;
}

void *func_producer(void *arg)
{
    arg = arg;
    struct timespec tv;

    // Write some data
    ssize_t written;
    char test_str[] = "0123456789";
    tv.tv_sec = 1;
    while(1)
    {
        pthread_mutex_lock(&rand_mutex);
        pthread_cond_timedwait(&prod_cond, &rand_mutex, &tv);
        //pthread_cond_wait(&prod_cond, &rand_mutex);
        //sleep(1);
        while (1)
        {
            written = cb_write(&cb, test_str, strlen(test_str));
            if(written <= 0)
            {
                //pthread_cond_signal(&cons_cond);
                pthread_cond_broadcast(&cons_cond);
                printf("error: Wrote %ld bytes\n", written);
                break;
            }
            printf("Wrote %ld bytes\n", written);
        }
        pthread_mutex_unlock(&rand_mutex);
    }

    return NULL;
}

void *func_consumer(void *arg)
{
    arg = arg;
    struct timespec tv;

    // Read the data back
    ssize_t read_len;
    char read_buf[20];

    tv.tv_sec = 1;

    while(1)
    {
        //sleep(1);
        pthread_mutex_lock(&rand_mutex);
        pthread_cond_timedwait(&cons_cond, &rand_mutex, &tv);
        //pthread_cond_wait(&cons_cond, &rand_mutex);
        while(1)
        {
            memset(read_buf, 0, sizeof(read_buf));
            read_len = cb_read(&cb, read_buf, 10);
            if(read_len <=0)
            {
                //pthread_cond_signal(&prod_cond);
                pthread_cond_broadcast(&prod_cond);
                //sleep(1);
                printf("error: Read %ld bytes: '%s'\n", read_len, read_buf);
                break;
            }
            printf("Read %ld bytes: '%s' out\n", read_len, read_buf);

        }
        pthread_mutex_unlock(&rand_mutex);
    }

    return NULL;
}

// gcc -g -O0 -std=c99 -Wall -Wextra -pedantic -pthread test.c -o string_ring_buffer
// Example usage
int main() {
    int i;
    pthread_t  t_prod[10];
    pthread_t  t_cons[10];

    cb_init(&cb, BUFFER_SIZE);


    for(i=0; i<5; i++)
    {
        pthread_create(&t_prod[i], NULL, func_producer, NULL);
        pthread_create(&t_cons[i], NULL, func_consumer, NULL);
    }

    for(i=0; i<5; i++)
    {
        pthread_join(t_prod[i], NULL);    
        pthread_join(t_cons[i], NULL);    
    }

    // Clean up
    cb_destroy(&cb);

    return 0;
}
 

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值