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);
}
相关推荐
hjjdebug31 分钟前
constexpr 关键字的意义(入门)
c++·constexpr
虾球xz2 小时前
游戏引擎学习第282天:Z轴移动与摄像机运动
c++·学习·游戏引擎
.小墨迹2 小时前
Apollo学习——planning模块(3)之planning_base
linux·开发语言·c++·学习·自动驾驶
龙湾开发2 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(一)过程式凹凸贴图
c++·笔记·学习·3d·图形渲染
德亦周2 小时前
如何在Mac电脑上的VScode去配置C/C++环境
c++·vscode·macos
XiaoyaoCarter3 小时前
每日一道leetcode(新学数据结构版)
数据结构·c++·算法·leetcode·职场和发展·哈希算法·前缀树
八月的雨季 最後的冰吻3 小时前
SIP协议栈--osip源码梳理
linux·服务器·网络·c++·网络协议
fancy1661664 小时前
搜索二维矩阵 II
c++·算法·矩阵
freyazzr4 小时前
Leetcode刷题 | Day63_图论08_拓扑排序
数据结构·c++·算法·leetcode·图论
顾子茵4 小时前
c++从入门到精通(四)--动态内存,模板与泛型编程
java·开发语言·c++