本节体验下多线程。
python示例
在src/demo_python_pkg/demo_python_pkg/下新建文件,learn_thread.py
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节点,编译后运行。
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++示例
先下载依赖库
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,收到请回答。