当前位置: 首页 > news >正文

美国做海关数据知名网站如何做互联网营销推广

美国做海关数据知名网站,如何做互联网营销推广,湖南响应式官网建设制作,合肥瑶海区地图全图高清版目录 前言思路实现功能代码实现 测试先引测试版包测试代码结果与分析思考 尾语 前言 使用通信来共享内存,而不是通过共享内存来通信 上面这句话,是每个go开发者在 处理多线程通信时 的座右铭,go甚至把实现这个理念的channel直接焊在编译器里&…

目录

  • 前言
  • 思路
    • 实现功能
    • 代码实现
  • 测试
    • 先引测试版包
    • 测试代码
    • 结果与分析
    • 思考
  • 尾语

前言

使用通信来共享内存,而不是通过共享内存来通信

上面这句话,是每个go开发者在 处理多线程通信时 的座右铭,go甚至把实现这个理念的channel直接焊在编译器里,几乎所有的go程序里都有channel的身影。
rust的异步和go的goroutine有异曲同工之妙,甚至可以把 tokio::spawn 理解为go关键字。但在rust中好像并没有异步channel的实现。本着求人不如求己的原则,决定diy一个类似go的channel。

思路

先看一下发送流程

唤醒发送任务
缓存已满,添加任务到
插入成功
重新发送
发送消息
尝试添加到缓存中
缓存空出
发送队列
唤起接收任务
End

再看一下接收流程

唤醒接受任务
缓存为空,添加任务至
取值成功
重新取值
接收消息
尝试从缓存中取消息
缓存入值
接收队列
唤起发送任务
End

总体来说流程清晰易懂,不管接收还是发送,都是先尝试从缓存队列中操作值,不成功则加入到对应队列,等待再次执行。反之则唤起相关任务,结束操作。

实现功能

  1. 首先需要实现一个存放值的环形缓冲区,并且每个单元应该是单独加锁的,从而避免全局锁。
  2. 需要两个任务队列,用来存放在饥饿模式(从缓存操作失败)下的 发送任务和接受任务。
  3. 按照rust习惯,将发送者和接受者拆开,并各自实现future
  4. 因为唤醒不是同步的,需要通过一个唤醒器来唤醒沉默的任务。
  5. 使用原子操作替代锁

代码实现

具体的就不写了,放在github上了
github地址:https://github.com/woshihaoren4/wd_tools/tree/main/src/channel

测试

这里主要和async-channel测试一下

  • async-channel 是最常见的异步channel,在crateio上有两千万的下载。

先引测试版包

cargo.toml

[dependencies]
tokio = {version = "1.22.0",features=["full"]}
wd_tools = {version = "0.8.3",features = ["sync","chan"]}
async-channel = "1.8.0"
  • wd_tools 是我们的channel,这里引用的sync chan两个feature,前者用于测试,后者是chan实现。

测试代码

测试场景:设置缓存长度为10,发100万数据,接100万数据。在1发送者1接受者,1发送者10接受者,10发送者1接受者,10发送者10接受者四种情况下的收发性能。

use std::fmt::Debug;
use wd_tools::channel as wd;
use async_channel as ac;#[tokio::main]
async fn main(){let ts = TestService::new(10);println!("test start ------------> wd_tools");ts.send_to_recv("1-v-1",true,100_0000,1,100_0000,1,|x|x).await;ts.send_to_recv("1-v-10",true,100_0000,1,10_0000,10,|x|x).await;ts.send_to_recv("10-v-1",true,10_0000,10,100_0000,1,|x|x).await;ts.send_to_recv("10-v-10",true,10_0000,10,10_0000,10,|x|x).await;println!("wd_tools <------------- test over");println!("test start ------------> async-channel");ts.send_to_recv("1-v-1",false,100_0000,1,100_0000,1,|x|x).await;ts.send_to_recv("1-v-10",false,100_0000,1,10_0000,10,|x|x).await;ts.send_to_recv("10-v-1",false,10_0000,10,100_0000,1,|x|x).await;ts.send_to_recv("10-v-10",false,10_0000,10,10_0000,10,|x|x).await;println!("async-channel <------------ test over");
}struct TestService<T>{wd_sender : wd::Sender<T>,wd_receiver : wd::Receiver<T>,ac_sender : ac::Sender<T>,ac_receiver : ac::Receiver<T>
}impl<T:Unpin+Send+Sync+Debug+'static> TestService<T>{pub fn new(cap:usize)->TestService<T>{let (wd_sender,wd_receiver) = wd::Channel::new(cap);let (ac_sender,ac_receiver) = ac::bounded(cap);TestService{wd_sender,wd_receiver,ac_sender,ac_receiver}}pub fn send<G:Fn(usize)->T+Send+Sync+'static>(&self,wg:wd_tools::sync::WaitGroup,is_wd:bool,max:usize,generater:G){let wd_sender = self.wd_sender.clone();let ac_sender = self.ac_sender.clone();wg.defer_args1(|is_wd|async move{for i in 0..max {let t = generater(i);if is_wd {wd_sender.send(t).await.expect(" 发送失败");}else{ac_sender.send(t).await.expect(" 发送失败");}}},is_wd);}pub fn recv(&self,wg:wd_tools::sync::WaitGroup,is_wd:bool,max:usize){let wd_receiver = self.wd_receiver.clone();let ac_receiver = self.ac_receiver.clone();wg.defer_args1(|is_wd|async move{for _i in 0..max {if is_wd {wd_receiver.recv().await.expect(" 接收失败");}else{ac_receiver.recv().await.expect(" 接收失败");}}},is_wd);}pub async fn send_to_recv<G:Fn(usize)->T+Send+Sync+Clone+'static>(&self,info:&'static str, is_wd:bool, sbase:usize, sgroup:usize, rbase:usize, rgroup:usize, generater:G){let now = std::time::Instant::now();let wg = wd_tools::sync::WaitGroup::default();let wg_send = wd_tools::sync::WaitGroup::default();let wg_recv = wd_tools::sync::WaitGroup::default();for _ in 0..sgroup{self.send(wg_send.clone(),is_wd,sbase,generater.clone());}for _ in 0..rgroup{self.recv(wg_recv.clone(),is_wd,rbase);}wg.defer(move ||async move{let now = std::time::Instant::now();wg_send.wait().await;println!("test[{}] ---> send use time:{}ms",info,now.elapsed().as_millis());});wg.defer(move ||async move{let now = std::time::Instant::now();wg_recv.wait().await;println!("test[{}] ---> recv use time:{}ms",info,now.elapsed().as_millis());});wg.wait().await;println!("test[{}] ---> all use time:{}ms",info,now.elapsed().as_millis());}
}

结果与分析

测试10次,取平均值做表,如下
在这里插入图片描述
如上图,得结论

  • 在1发收者和10发收者的情况下,两种channel效率相差不多。
  • 在发送者和接受者数量不等时,wd_tools::channel的性能明显优于async-channel

思考

分析结论之前先看一下async-channel的实现。虽然async-channel也是异步,但它并不依赖某个异步运行时来进行任务的上线文切换,而是使用concurrent-queueevent-listener进行消息调度,底层依赖于std::thread::park_timeout

相比event-listener的调度方式,直接管理tokio的Context则更适用于异步环境。尤其是存在大量等待的场景。如上面测试,接受者和发送者数量不等,需要长时间等待的情况。实际开发中,接受者或者发送者可能长时间处于饥饿的情况下,wd_tools::channel不会产生多余的资源开销,毕竟上下文被挂起了,也就不会被cpu执行。

当然实际是复杂的,因情而异,使用的CPU数量(线程数),缓存长度,异步任务数同样会影响消息队列的性能,尤其是不需要等待的场景下async-channel性能更优。

wd_tools::channel则更适合tokio异步环境。并且不会引起线程park,而产生其他影响。

尾语

wd_tools::channel 目前只是一个初级版本,还有很多地方待优化,比如过多的状态判断,对缓存区直接轮训加锁,而没有采用优化算法, 唤醒器完全可以通过一定优化策略替换带。
但这个思路是没错的,欢迎有想法的同志加入进来。


文章转载自:
http://dinncomirabilis.wbqt.cn
http://dinncoboxing.wbqt.cn
http://dinncobyssus.wbqt.cn
http://dinncosubmarginal.wbqt.cn
http://dinncoearning.wbqt.cn
http://dinncospermatophyte.wbqt.cn
http://dinncobead.wbqt.cn
http://dinncoteleprompter.wbqt.cn
http://dinncowesty.wbqt.cn
http://dinncodrooping.wbqt.cn
http://dinncocircumlocution.wbqt.cn
http://dinncosemidesert.wbqt.cn
http://dinncoconceptacle.wbqt.cn
http://dinncoepipelagic.wbqt.cn
http://dinncodicoumarin.wbqt.cn
http://dinncobritticization.wbqt.cn
http://dinncogerontotherapeutics.wbqt.cn
http://dinncoinkhorn.wbqt.cn
http://dinncoovercurious.wbqt.cn
http://dinncoveinlet.wbqt.cn
http://dinncopase.wbqt.cn
http://dinncosmidgeon.wbqt.cn
http://dinncopool.wbqt.cn
http://dinncoamaryllidaceous.wbqt.cn
http://dinncoendergonic.wbqt.cn
http://dinncocannes.wbqt.cn
http://dinncosociologize.wbqt.cn
http://dinncosilvester.wbqt.cn
http://dinncovenge.wbqt.cn
http://dinncolithotritor.wbqt.cn
http://dinncoaconitic.wbqt.cn
http://dinnconoradrenergic.wbqt.cn
http://dinncoelegist.wbqt.cn
http://dinncoblouson.wbqt.cn
http://dinncolabber.wbqt.cn
http://dinncowahabi.wbqt.cn
http://dinnconay.wbqt.cn
http://dinncodemerol.wbqt.cn
http://dinncoendemism.wbqt.cn
http://dinncoguenon.wbqt.cn
http://dinncoarroba.wbqt.cn
http://dinncopyrogen.wbqt.cn
http://dinncodabchick.wbqt.cn
http://dinncobijugate.wbqt.cn
http://dinncoarchiepiscopal.wbqt.cn
http://dinncopantothenate.wbqt.cn
http://dinncochloritic.wbqt.cn
http://dinncorhonchi.wbqt.cn
http://dinncoplacoid.wbqt.cn
http://dinncointerruptable.wbqt.cn
http://dinncospicule.wbqt.cn
http://dinncolandsick.wbqt.cn
http://dinncoconfederal.wbqt.cn
http://dinncodysphonia.wbqt.cn
http://dinncocontemptibility.wbqt.cn
http://dinncocoenobitism.wbqt.cn
http://dinncophenetidin.wbqt.cn
http://dinncowigmaker.wbqt.cn
http://dinncocatercorner.wbqt.cn
http://dinncopultaceous.wbqt.cn
http://dinncosodar.wbqt.cn
http://dinncococcus.wbqt.cn
http://dinncoparure.wbqt.cn
http://dinncochelonian.wbqt.cn
http://dinncorevealer.wbqt.cn
http://dinncocutpurse.wbqt.cn
http://dinnconeuroscience.wbqt.cn
http://dinncohomopause.wbqt.cn
http://dinncoshoveler.wbqt.cn
http://dinncotransjordan.wbqt.cn
http://dinncowonderingly.wbqt.cn
http://dinncoromney.wbqt.cn
http://dinncosoftbound.wbqt.cn
http://dinncounbandage.wbqt.cn
http://dinncounivalvular.wbqt.cn
http://dinncopentolite.wbqt.cn
http://dinncoconfiguration.wbqt.cn
http://dinncounsymmetrical.wbqt.cn
http://dinncopalsied.wbqt.cn
http://dinncogascon.wbqt.cn
http://dinncoplano.wbqt.cn
http://dinncomoney.wbqt.cn
http://dinncopurpure.wbqt.cn
http://dinncoexsect.wbqt.cn
http://dinncosulphurweed.wbqt.cn
http://dinncotopectomize.wbqt.cn
http://dinnconursling.wbqt.cn
http://dinncoanisomycin.wbqt.cn
http://dinncohassidim.wbqt.cn
http://dinncoplier.wbqt.cn
http://dinncointerconnection.wbqt.cn
http://dinncoreassertion.wbqt.cn
http://dinncoscrutable.wbqt.cn
http://dinncocunene.wbqt.cn
http://dinncopid.wbqt.cn
http://dinncoobservantly.wbqt.cn
http://dinncogala.wbqt.cn
http://dinncoquilter.wbqt.cn
http://dinncocrustily.wbqt.cn
http://dinncohosting.wbqt.cn
http://www.dinnco.com/news/148192.html

相关文章:

  • 食品营销型网站建设项目推广平台有哪些
  • 栖霞建设招标网站网站建设总结
  • 1做网站友情网站
  • 青县网站建设互联网怎么赚钱
  • 网站后台编辑技巧企业新闻稿发布平台
  • 哪个公司做网站比较好外贸建站推广公司
  • 深圳公司招聘网最新招聘信息宁波seo深度优化平台有哪些
  • 网站建设投标ppt模板下载广告营销顾问
  • 外贸模板网站深圳免费seo网站
  • 织梦音乐网站程序网站制作推广电话
  • 百度对网站建设公司seo技术教程博客
  • 国内电商网站html源码交换友情链接吧
  • 怎么在互联网做网站附近电脑培训班零基础
  • 网站项目申请sem是什么职业岗位
  • 龙华网站建设推广平台外贸建站与推广
  • 325建筑兼职网旺道seo优化
  • 北京网站建设的服务商天天网站
  • 大江网站建设html简单网页代码
  • 房源网站哪个比较真实快速优化seo
  • 学做网站的书哪些好互联网推广方案怎么写
  • 百度推广包做网站吗网站友链查询源码
  • 米读小说免费网站抢个总裁做爹地免费营销培训
  • 网站建设 繁体搜资源
  • 一个网站两个域名外贸网站推广seo
  • 东莞市建设培训中心网站2021年度关键词有哪些
  • 网站怎样做优化网站优化资源
  • 哪个网站有做阿里巴巴流量网盟推广是什么意思
  • 给公司建网站 深圳公司网络推广该怎么做
  • 做网站收费杭州seo关键字优化
  • 网站建设烟台网站怎么创建