brpc: bthread使用

使用bthread并发编程

cpp 复制代码
#include <gflags/gflags.h>
#include <butil/logging.h>
#include <bthread/bthread.h>

static void* func(void* args) {
    std::string* num = static_cast<std::string*>(args);
    for(int i = 0; i < 5; i++) {
        LOG(INFO) << *num;
        bthread_usleep(1000);
    }
    return NULL;
}


int main() {
    bthread_t th1, th2;
    std::string a = "bthread:A", b = "bthread:B", c = "bthread:C";
    if (bthread_start_background(&th1, NULL, func, static_cast<void*>(&a)) != 0) {
        LOG(ERROR) << "Fail to create bthread for part1";
    }
    if (bthread_start_background(&th2, NULL, func, static_cast<void*>(&b)) != 0) {
        LOG(ERROR) << "Fail to create bthread for part2";
    }
    func(static_cast<void*>(&c));
    bthread_join(th1, NULL);
    bthread_join(th2, NULL);
}

thread 栈切换事例

cpp 复制代码
#include <bthread/context.h>
#include <iostream>

::bthread_fcontext_t fc1;
::bthread_fcontext_t fc2;
::bthread_fcontext_t fc_tmp;
intptr_t  g_num1 = 0;
intptr_t  g_num2 = 0;

static void jumper1(intptr_t param) {
    for(int i = 0; i < 9; i++) {
        printf("context1: g_num1 = %ld, then jump to context2\n", ++g_num1);
        ::bthread_jump_fcontext(&fc1, fc2, 0);
    }
    // 最后结尾,jump到原始上下文中,继续执行
    printf("context1: g_num1 = %ld, finally, jump to main\n", ++g_num1);
    ::bthread_jump_fcontext(&fc1, fc_tmp, 0);
}
static void jumper2(intptr_t param) {
    for(int i = 0; i < 10; i++) {
        printf("context2: g_num2 = %ld, then jump to context1\n", ++g_num2);
        ::bthread_jump_fcontext(&fc2, fc1, 0);
    }
}

int main() {
    static const std::size_t stack_size = 8192;

    // 创建两个上下文
    void *sp1 = ::malloc(stack_size);
    fc1 = ::bthread_make_fcontext((char*)sp1 + stack_size, stack_size, jumper1);

    void *sp2 = ::malloc(stack_size);
    fc2 = ::bthread_make_fcontext((char*)sp2 + stack_size, stack_size, jumper2); 

    // 将当前上下文保存到fc_tmp,并切换上下为fc2
    ::bthread_jump_fcontext(&fc_tmp, fc2, 0);

    printf("done\n");

    ::free(sp1);
    ::free(sp2);
    return 0;
}

ExecutionQueue 的使用

ExecutionQueue是一个mpsc队列,即线程安全的多生产者单消费者队列

cpp 复制代码
#include <bthread/execution_queue.h>
#include <bthread/bthread.h>
class DemoTask {
public:
    void run(int);
};

void DemoTask::run(int count) {
    LOG(INFO) << "DemoTask::run(" << count << ")";
}

int comsume(void *meta, bthread::TaskIterator<DemoTask*> &iter) {
    if(iter.is_queue_stopped()) {
        return 0;
    }
    int count = 0;
    for(; iter; ++iter) {
        DemoTask *task = *iter;
        task->run(++count);
    }
    return 0;
}

int main() {
    bthread::ExecutionQueueId<DemoTask*> exe_queue;
    int ret = bthread::execution_queue_start(&exe_queue, nullptr, comsume, nullptr);
    DemoTask *task = new DemoTask();
    ret = bthread::execution_queue_execute(exe_queue, task);
    bthread_usleep(10);
}
相关推荐
程序猿阿伟5 分钟前
《C++高效图形用户界面(GUI)开发:探索与实践》
开发语言·c++
阿客不是客19 分钟前
深入计算机语言之C++:C到C++的过度
c++
LN-ZMOI26 分钟前
c++学习笔记1
c++·笔记·学习
no_play_no_games29 分钟前
「3.3」虫洞 Wormholes
数据结构·c++·算法·图论
￴ㅤ￴￴ㅤ9527超级帅30 分钟前
LeetCode hot100---数组及矩阵专题(C++语言)
c++·leetcode·矩阵
五味香30 分钟前
C++学习,信号处理
android·c语言·开发语言·c++·学习·算法·信号处理
gobeyye1 小时前
spring loC&DI 详解
java·spring·rpc
TANGLONG2221 小时前
【C语言】数据在内存中的存储(万字解析)
java·c语言·c++·python·考研·面试·蓝桥杯
summ1ts1 小时前
组合数求法汇总
c++·数学·算法·离散数学·组合数学
牛魔王的小怪兽1 小时前
ROS C++ : 使用ros::AsyncSpinner,实现多线程处理ROS消息
c++·ros