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);
}
相关推荐
apocelipes8 分钟前
C++20新增属性[[no_unique_address]]详解
c++·性能优化
十五年专注C++开发37 分钟前
cargs: 一个轻量级跨平台命令行参数解析库
linux·c++·windows·跨平台·命令行参数解析
宁静致远202138 分钟前
【C++设计模式】第二篇:策略模式(Strategy)--从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
c++·设计模式·策略模式
·前路漫漫亦灿灿1 小时前
C++-类型转换
开发语言·c++
CHANG_THE_WORLD1 小时前
C++ 并发编程指南 并发设计模式:Actor vs. CSP (生活场景版)
c++·设计模式·生活
mahuifa1 小时前
C++(Qt)软件调试---bug排查记录(36)
c++·bug·软件调试
晚风(●•σ )7 小时前
C++语言程序设计——06 字符串
开发语言·c++
晚云与城7 小时前
今日分享:C++ -- list 容器
开发语言·c++
兰雪簪轩8 小时前
分布式通信平台测试报告
开发语言·网络·c++·网络协议·测试报告
只因在人海中多看了你一眼10 小时前
B.50.10.09-RPC核心原理与电商应用
qt·网络协议·rpc