brpc: bthread使用

使用bthread并发编程

#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 栈切换事例

#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队列,即线程安全的多生产者单消费者队列

#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);
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值