ros2笔记-2.5.3 多线程与回调函数

news/2025/1/10 6:56:35 标签: 笔记, 多线程, 回调函数, c++, python

本节体验下多线程

python示例

在src/demo_python_pkg/demo_python_pkg/下新建文件,learn_thread.py

python">import threading
import requests

class Download:
    def download(self,url,callback):
        print(f'线程:{threading.get_ident()} 开始下载:{url}')
        reponse = requests.get(url)
        reponse.encoding = 'utf-8'
        callback(url,reponse.text)

    def start_download(self,url,callback):
        thread  = threading.Thread(target=self.download,args=(url,callback))
        thread.start()    

def world_cout(url,result):

    print(f"{url}:{len(result)}->{result[:30]}")

def main():
    download = Download()
    download.start_download('https://fishros.com/d2lros2/#/humble/chapt1/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB',world_cout) 
    download.start_download('https://fishros.com/d2lros2/#/humble/chapt2/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB',world_cout) 
    download.start_download('https://fishros.com/d2lros2/#/humble/chapt3/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB',world_cout) 

python的线程库是threading,http请求库是requests.

Download 类定义了两个方法download、start_download。其中download 是真正的下载,start_download启动thread来运行目标函数download。

回调函数world_cout,用于处理下载完成的数据。main函数是入口,实例化一个Download类型的对象download,分别去下载,url 测试下。书上例子是自己造的TXT。

在setup.py添加learn_thread节点,编译后运行。

python">bohu@bohu-TM1701:~/2/2_ws$ colcon build
Starting >>> demo_cpp_pkg
Finished <<< demo_cpp_pkg [0.16s]                     
Starting >>> demo_python_pkg
Finished <<< demo_python_pkg [1.24s]          

Summary: 2 packages finished [1.75s]
bohu@bohu-TM1701:~/2/2_ws$ ros2 run demo_python_pkg learn_thread 
线程:126326222620224 开始下载:https://fishros.com/d2lros2/#/humble/chapt1/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB
线程:126326212134464 开始下载:https://fishros.com/d2lros2/#/humble/chapt2/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB
线程:126326126151232 开始下载:https://fishros.com/d2lros2/#/humble/chapt3/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB
https://fishros.com/d2lros2/#/humble/chapt1/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB:5794-><!DOCTYPE html>
<html lang="en
https://fishros.com/d2lros2/#/humble/chapt3/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB:5794-><!DOCTYPE html>
<html lang="en
https://fishros.com/d2lros2/#/humble/chapt2/%E7%AB%A0%E8%8A%82%E5%AF%BC%E8%AF%BB:5794-><!DOCTYPE html>
<html lang="en

C++示例

先下载依赖库

python">bohu@bohu-TM1701:~/2/2_ws/src/demo_cpp_pkg/include$ git clone https://gitee.com/ohhuo/cpp-httplib.git
正克隆到 'cpp-httplib'...
remote: Enumerating objects: 4527, done.
remote: Total 4527 (delta 0), reused 0 (delta 0), pack-reused 4527
接收对象中: 100% (4527/4527), 2.27 MiB | 2.55 MiB/s, 完成.
处理 delta 中: 100% (3057/3057), 完成.

下载完成后,还要在CMakeLists.txt 添加目录

include_directories(include) #包含include头文件目录

在2_ws/src/demo_cpp_pkg/src下新建learn_thread.cpp文件。

#include <iostream>
#include <thread>
#include <chrono> //时间相关
#include <functional>
#include <cpp-httplib/httplib.h>
using namespace std;

class Download
{

public:
    void download(const string &host,const string &path,const function<void(const 
          string &,const string &)> &callback)
          {
               cout<<" 线程ID: "<< this_thread::get_id() << endl;
               httplib::Client client(host);
               auto response = client.Get(path);
               if(response && response->status==200){
                callback(path,response->body);
               } 
          };
    void  start_download(const string &host,const string &path,const function<void(const 
          string &,const string &)> &callback)
          {
              auto download_fun = bind(&Download::download,this,placeholders::_1,
              placeholders::_2,placeholders::_3);
              thread thread(download_fun,host,path,callback);
              thread.detach();  
          };     

};

int main()
{
    auto d= Download();
    auto word_count = [](const string &path,const string &result) -> void{
        cout << "下载完成" << path <<""<<result.length()<<"->"<<result.substr(0,100)<< endl;
    };
    d.start_download("http://0.0.0.0:8000","/novel1.txt",word_count);
    d.start_download("http://0.0.0.0:8000","/novel2.txt",word_count);
    d.start_download("http://0.0.0.0:8000","/novel3.txt",word_count);

    this_thread::sleep_for(chrono::seconds(10));
    return 0;
}


 开头还是引用头文件。然后声明了Download类,添加了download函数和start_download函数。

download函数使用了httplib下载,start_download函数里面thread.detach(); 将线程与当前进程分离,使得线程可以后台运行。

main函数是入口,通过lambda创建了回调函数。并三次调用start_download 下载。最后延迟了10秒,防止程序直接退出。

在CMakeLists.txt 添加节点,编译运行。运行结果:

bohu@bohu-TM1701:~/2/2_ws$ ros2 run demo_cpp_pkg learn_thread
 线程ID: 138510887552576
 线程ID: 138510877066816
 线程ID: 138510747043392
下载完成/novel2.txt85-> BH8VYW,你好,这里是BH8ZZZ,你的信号是59,能否抄收我的信号?

下载完成/novel3.txt85-> BH8ZZZ,你好,这里是BH8VYW,你的信号是59,能够抄收你的信号。

下载完成/novel1.txt70->CQ,CQ,CQ,这里是BH8VYW,这里是BH8VYW,收到请回答。


http://www.niftyadmin.cn/n/5818316.html

相关文章

flowable mysql 表名大小写问题

在部署一个工作流项目&#xff08;flowable&#xff09;时&#xff0c;这边把测试库的表直接还原到正式环境&#xff0c;在启动后发现flowable又单独建了一套大写的表名表&#xff0c;之前因为是在windows下创建&#xff0c;表名默认是小写&#xff0c;windows下没有问题&#…

ASP.NET Core 实现微服务 -- Polly 服务降级熔断

在我们实施微服务之后&#xff0c;服务间的调用变的异常频繁。多个服务之间可能是互相依赖的关系。某个服务出现故障或者是服务间的网络出现故障都会造成服务调用的失败&#xff0c;进而影响到某个业务服务处理失败。某一个服务调用失败轻则造成当前相关业务无法处理&#xff1…

T-SQL语言的学习路线

T-SQL语言的学习路线 引言 在当今的数据驱动时代&#xff0c;掌握数据库语言尤为重要。而在众多数据库语言中&#xff0c;T-SQL&#xff08;Transact-SQL&#xff09;作为微软SQL Server的扩展语言&#xff0c;因其强大的功能和灵活性&#xff0c;成为了很多开发者和数据分析…

自然语言转 SQL:通过 One API 将 llama3 模型部署在 Bytebase SQL 编辑器

使用 Open AI 兼容的 API&#xff0c;可以在 Bytebase SQL 编辑器中使用自然语言查询数据库。 出于数据安全的考虑&#xff0c;私有部署大语言模型是一个较好的选择 – 本文选择功能强大的开源模型 llama3。 由于 OpenAI 默认阻止出站流量&#xff0c;为了简化网络配置&#…

python 文件读写with open模式r,r+,w,w+,a,a+的区别

模式可做操作若文件不存在是否覆盖r只能读报错-r可读可写报错是w只能写创建是w 可读可写创建是a  只能写创建否&#xff0c;追加写a可读可写创建否&#xff0c;追加写 例子&#xff1a; def file_operation():with open(/wzd/test.txt, moder) as f:# f.write(abc)r f.rea…

【LeetCode】力扣刷题热题100道(1-5题)附源码 链表 子串 中位数 回文子串(C++)

目录 1.两数之和 2.两数相加-链表 3.无重复字符的最长子串 4.寻找两个正序数组的中位数 5.最长回文子串 1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。…

【Flutter】使用ScrollController配合EasyRefresh实现列表预加载:在还未滑动到底部时加载下一页数据

需求/背景 在我们的业务场景中&#xff0c;列表的加载使用easy_refresh组件&#xff1a; https://pub.dev/packages/easy_refresh 大概效果是往上滑动到一定的offset会触发一个上滑加载&#xff0c;可以触发一些网络请求拉取列表后面的数据来展示。 这种模式一般在一页翻完…

uvm的m_sequencer和p_sequencer

p_sequencer 基本概念 p_sequencer是一个指向uvm_sequencer&#xff08;序列发生器&#xff09;的指针&#xff08;句柄&#xff09;。它在uvm_sequence&#xff08;序列&#xff09;中使用&#xff0c;用于访问序列发生器的成员和方法。通过uvm_declare_p_sequencer宏来声明…