libco —— 安装与使用

libco的安装

可以直接从 Tencent 的 GitHub 仓库中拉取源码:

ubuntu@VM-0-2-ubuntu:~/libco$ git clone https://github.com/Tencent/libco.git

然后 转到下载的/libco目录,执行make命令

ubuntu@VM-0-2-ubuntu:~/libco$ cd libco/
ubuntu@VM-0-2-ubuntu:~/libco/libco$ make

然后将其中的不带example的头文件拷贝到 /usr/include路径下:
在这里插入图片描述

然后拉取之后,会在lib目录下有个libcolib.a 文件,拷贝到/usr/lib下。

libco库的简单使用

我们现在使用协程来模拟一下经典线程的生产者和消费者模型:

#include <libco/co_closure.h>
#include <libco/co_comm.h>
#include <libco/co_routine.h>

#include <stdlib.h>
#include <cstdio>
#include <queue>
#include <iostream>
using namespace std;

// 资源
struct stTask_t
{
    int id;
};

// 存储资源的队列
struct stEnv_t
{
    stCoCond_t *cond;
    queue<stTask_t *> task_queue;
};

// 生产者
void *Producer(void *args)
{
    co_enable_hook_sys();
    stEnv_t *env = (stEnv_t *)args;
    int id = 0;
    while (true)
    {
        stTask_t *task = (stTask_t *)calloc(1, sizeof(stTask_t));
        task->id = id++;
        env->task_queue.push(task);
        cout << "produce task " << task->id << endl;
        co_cond_signal(env->cond);
        poll(NULL, 0, 1000);
    }
    return NULL;
}

// 消费者
void *Consumer(void *args)
{
    co_enable_hook_sys();
    stEnv_t *env = (stEnv_t *)args;
    while (true)
    {
        if (env->task_queue.empty())
        {
            co_cond_timedwait(env->cond, -1);
            continue;
        }
        stTask_t *task = env->task_queue.front();
        env->task_queue.pop();
        cout << "consume task " << task->id << endl;
        free(task);
    }
    return NULL;
}

int main()
{
    stEnv_t *env = new stEnv_t;
    env->cond = co_cond_alloc();

    stCoRoutine_t *consumer_routine;
    // 创建协程
    co_create(&consumer_routine, nullptr, Consumer, env);
    // 启动协程
    co_resume(consumer_routine);

    stCoRoutine_t *producer_routine;
    co_create(&producer_routine, nullptr, Producer, env);
    co_resume(producer_routine);

    //创建eventloop,事件循环
    co_eventloop(co_get_epoll_ct(), nullptr, nullptr);
    return 0;
}

输出:

ubuntu@VM-0-2-ubuntu:~/libco/libco/bin$ ./test1
produce task 0
consume task 0
produce task 1
consume task 1
produce task 2
consume task 2
produce task 3
consume task 3
produce task 4
consume task 4
produce task 5
consume task 5
produce task 6
consume task 6
produce task 7
consume task 7

至于具体是什么可以参照协程专栏的其他博文,这里只介绍协程使用的流程。

首先从main函数开始看,我们可以看到一个结构叫做stCoRuntin_t,他是co_create函数的第一个参数。然后由co_create创建一个协程对象,其中第二个参数为nullptr,第三个参数是此协程要执行的函数,第四个则是这个函数所需的变量。而创建出来的协程对象也就是协程所需的相关资源。

协程创建之后,调用co_resume函数去启动这个协程。最后,像线程一样,线程创建后需要调用pthread_join等待子线程退出,而这里我们调用了co_eventloop()函数达到一样的目的。

参考文献

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
如果你已经下载了CANopenNode的Qt版本,那么可以按照以下步骤来使用: 1. 打开Qt Creator,创建一个新项目。 2. 在项目中,添加CANopenNode库。在.pro文件中添加以下行: ``` INCLUDEPATH += <path-to-the-CANopenNode-Qt>/CANopenNode/ LIBS += <path-to-the-CANopenNode-Qt>/CANopenNode/lib/libCO_CANopen.a ``` 注意替换`<path-to-the-CANopenNode-Qt>`为你自己的路径。 3. 在项目中创建一个CO配置结构体,并通过CO函数初始化它。例如: ``` #include "CANopen.h" static CO_CANbitRateData_t canBitRate = {500000, 7, 2, 1, 0}; static CO_CANmodule_t *canModule; static CO_NMT_t *NMT; static CO_SDO_t *SDO; static CO_EM_t *EM; static CO_SYNC_t *SYNC; static CO_TIME_t *TIME; static CO_RPDO_t *RPDO1; static CO_TPDO_t *TPDO1; static CO_RPDO_t *RPDO2; static CO_TPDO_t *TPDO2; static CO_RPDO_t *RPDO3; static CO_TPDO_t *TPDO3; static CO_RPDO_t *RPDO4; static CO_TPDO_t *TPDO4; static CO_SDOclient_t *SDOclient; static CO_t CO = {}; void initCO(void) { CO_CANinit(canModule, &canBitRate); CO_Init(&CO, NULL, 0, NULL); NMT = CO_NMT_create(&CO, 0x01, 0x00); SDO = CO_SDO_create(&CO, 0x600 + CO_NODE_ID, 0x580 + CO_NODE_ID); EM = CO_EM_create(&CO, 8); SYNC = CO_SYNC_create(&CO, 0); TIME = CO_TIME_create(&CO, NULL); RPDO1 = CO_RPDO_create(&CO, 1); TPDO1 = CO_TPDO_create(&CO, 1); RPDO2 = CO_RPDO_create(&CO, 2); TPDO2 = CO_TPDO_create(&CO, 2); RPDO3 = CO_RPDO_create(&CO, 3); TPDO3 = CO_TPDO_create(&CO, 3); RPDO4 = CO_RPDO_create(&CO, 4); TPDO4 = CO_TPDO_create(&CO, 4); SDOclient = CO_SDOclient_create(&CO, 0); } ``` 这里创建了CO配置结构体,并初始化了CANopenNode中的各个对象。 4. 在项目中添加CANopenNode的线程。例如: ``` #include <QThread> #include "CANopen.h" class CANopenThread : public QThread { public: CANopenThread(CO_t *co) : m_co(co) { } void run() override { CO_run(m_co); } private: CO_t *m_co; }; static CANopenThread *coThread; void startCO(void) { coThread = new CANopenThread(&CO); coThread->start(); } ``` 这里创建了一个Qt线程,并将CANopenNode的`CO_run()`函数放到线程中运行。 5. 在项目中,通过SDO函数读写节点对象字典。例如: ``` #include "CANopen.h" void readSDO(void) { uint32_t value; CO_SDO_read(SDO, 0x1017, 0x00, &value, 4); } void writeSDO(void) { uint32_t value = 0x01; CO_SDO_write(SDO, 0x1017, 0x00, &value, 4); } ``` 这里演示了如何使用SDO函数读写节点对象字典中的一个对象。 以上是Qt版本的CANopenNode使用的基本步骤,你可以根据自己的需要进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shenmingik

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值