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);
}
相关推荐
GiraKoo6 分钟前
【GiraKoo】C++11的新特性
c++·后端
不午睡的探索者9 分钟前
告别性能瓶颈!Python 量化工程师,进击 C++ 高性能量化交易的“必修课”!
c++·github
OpenC++10 分钟前
【C++】观察者模式
c++·观察者模式·设计模式
老歌老听老掉牙19 分钟前
粒子群优化算法实现与多维函数优化应用
c++·pso·粒子群算法
myloveasuka43 分钟前
信号操作集函数
linux·运维·服务器·c语言·c++·vscode
山野万里__1 小时前
C++与Java内存共享技术:跨平台与跨语言实现指南
android·java·c++·笔记
Mr_Xuhhh2 小时前
网络基础(1)
c语言·开发语言·网络·c++·qt·算法
醇醛酸醚酮酯2 小时前
std::promise和std::future的使用示例——单线程多链接、多线程单链接
网络·c++·算法
背影疾风2 小时前
C++之路:类基础、构造析构、拷贝构造函数
linux·开发语言·c++
程序员弘羽3 小时前
C++ 第四阶段 内存管理 - 第二节:避免内存泄漏的技巧
java·jvm·c++