Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Swoole 4.4:支持 CURL 协程化

Swoole 4.4:支持 CURL 协程化

作者头像
猿哥
发布于 2019-06-12 05:45:35
发布于 2019-06-12 05:45:35
60600
代码可运行
举报
文章被收录于专栏:Web技术布道师Web技术布道师
运行总次数:0
代码可运行

4.4之前的版本中,Swoole一直不支持CURL协程化,在代码中无法使用curl。由于curl使用了libcurl库实现,无法直接hook它的socket4.4版本使用Swoole\Coroutine\Http\Client模拟实现了curlAPI,并在底层替换了curl_init等函数的C Handler

提示

  • CURL Hook的特性尚处于试验阶段,请勿在生产环境中直接使用
  • 暂不支持文件上传、CURL Multi
  • 仍然需要依赖curl,请务必安装curl扩展

支持的特性列表

  • GET/POST
  • Header
  • Cookie
  • Https

经过验证Guzzle CURL完全可以使用

开启

使用Runtime::enableCoroutine来开启CURL Hook

默认不开启CURL Hook

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_CURL);

使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$n = 10;
while($n--) {
    go(function () {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "http://www.xinhuanet.com/");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $output = curl_exec($ch);
        if ($output === FALSE) {
            echo "CURL Error:" . curl_error($ch);
        }
        curl_close($ch);
        echo strlen($output) . " bytes\n";
    });
}

要将上面两段代码合并到一个文件中执行

运行结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
htf@LAPTOP-0K15EFQI:~/swoole-src/examples$ time php curl.php
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes

real    0m0.534s
user    0m0.031s
sys     0m0.297s

可以看到整个程序是并行的,进程没有任何阻塞。

strace 跟踪

使用strace跟踪发现,所有系统调用均变成epoll+socket的异步非阻塞调用了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
epoll_create(512)                       = 3
mmap(NULL, 258048, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc038a50000
mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc028910000
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 4
fcntl(4, F_GETFL)                       = 0x80002 (flags O_RDWR|O_CLOEXEC)
fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK|O_CLOEXEC) = 0
setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
pipe([5, 6])                            = 0
fcntl(5, F_GETFL)                       = 0 (flags O_RDONLY)
fcntl(5, F_SETFL, O_RDONLY|O_NONBLOCK)  = 0
fcntl(6, F_GETFL)                       = 0x1 (flags O_WRONLY)
fcntl(6, F_SETFL, O_WRONLY|O_NONBLOCK)  = 0
epoll_ctl(3, EPOLL_CTL_ADD, 5, {EPOLLIN, {u32=5, u64=34359738373}}) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc028100000
mprotect(0x7fc028101000, 8388608, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x7fc0288ffb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc0289009d0, tls=0x7fc028900700, child_tidptr=0x7fc0289009d0) = 55
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc0237f0000
mprotect(0x7fc0237f1000, 8388608, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x7fc023fefb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc023ff09d0, tls=0x7fc023ff0700, child_tidptr=0x7fc023ff09d0) = 56
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc022fe0000
mprotect(0x7fc022fe1000, 8388608, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x7fc0237dfb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc0237e09d0, tls=0x7fc0237e0700, child_tidptr=0x7fc0237e09d0) = 57
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc0227d0000
mprotect(0x7fc0227d1000, 8388608, PROT_READ|PROT_WRI
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP技术大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
10张图22段代码,万字长文带你搞懂虚拟内存模型和malloc内部原理
摊牌了,不装了,其实我是程序喵辛苦工作一天还要回家编辑公众号到大半夜的老婆,希望各位大哥能踊跃转发,完成我一千阅读量的KPI(梦想),谢谢!
C语言与CPP编程
2020/12/02
2070
10张图22段代码,万字长文带你搞懂虚拟内存模型和malloc内部原理
Linux 命令(137)—— strace 命令
strace 命令是一个集诊断、调试、统计于一体的工具,我们可以使用 strace 对程序的系统调用和信号传递的跟踪结果来对程序进行分析,以达到解决问题或者是了解程序工作过程的目的。当然strace 与专业的调试工具比如说 gdb 之类的是没法相比的,因为它不是一个专业的调试器。
恋喵大鲤鱼
2020/04/13
8.5K0
使用golang的net包进行域名解析过程分析
我们都知道,在计算机的世界,建立连接都是需要依靠五元组的(源ip,源端口,目的ip,目的端口,协议),而在实际用户使用过程中,浏览器会帮我们识别和管理源ip和端口以及协议(http,https),协议确定后其实目的端口也就确定了(80或443). 因此整个DNS系统要解决的问题就是将用户在浏览器中输入的域名最终转换成可识别的目的ip,进而进行连接通信。下面以一个简单例子来分析下dns解析的过程.
BGBiao
2019/09/11
13.6K0
futex验证_fulvic
#include <semaphore.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h>
全栈程序员站长
2022/11/08
3080
线程的创建以及线程的本质
上节详细学习了进程的创建,通过实例学习了fork和vfork的区别。本节将学习线程的创建,只涉及应用层的线程,内核线程的创建在后面学习。
DragonKingZhu
2020/03/24
1.7K0
线程的创建以及线程的本质
Java线程在操作系统层面的一些'蛛丝马迹'
作为Java开发人员,在日常的开发工作中,无时无刻不在和线程打交道.本篇文章并不是讲解线程的相关知识.而是在Linux平台使用一些命令工具,观察下Java线程在操作系统层面的一些'蛛丝马迹'.
书唐瑞
2022/06/02
1940
Java线程在操作系统层面的一些'蛛丝马迹'
线程与栈那些事
网上很多文章都说,线程比较轻量级 lightweight,进程比较重量级,首先我们来看看这两者到底的区别和联系在哪里。
挖坑的张师傅
2022/05/13
6840
线程与栈那些事
JAVA中的I/O模型-BIO
上面的主文件我们只需要关注2819、2835、2836以及2844四行,前三行分别对应的是socket的创建,以及绑定端口和监听事件。而后面的poll则是一个等待事件函数,我们接下来看看方法描述。
Montos
2021/03/10
4860
JAVA中的I/O模型-BIO
无法获取指向控制台的文件描述符 (couldn't get a file descriptor referring to the console)
最近收拾东西,从一堆杂物里翻出来尘封四年多的树莓派 3B 主机来,打扫打扫灰尘,接上电源,居然还能通过之前设置好的 VNC 连上。欣慰之余,开始 clone 我的 git 项目,为它们拓展一个新的平台。在执行 cnblogs 项目 (参考《博客园排名预测 》) 对应的绘图命令时,趋势图、预测图是生成了,但没有自动打开图片,这个问题经过一番探索居然解决了,这篇文章就来分享一下解决问题的过程。
海海
2022/08/31
3.7K0
无法获取指向控制台的文件描述符 (couldn't get a file descriptor referring to the console)
Swoole v4.7 版本预览之支持 c-ares
c-ares 是一个异步 DNS 解析库。它适用于需要在不阻塞的情况下执行 DNS 查询或需要并行执行多个 DNS 查询的应用程序。
沈唁
2021/07/23
8140
这条命令有可能断送DBA职业生涯,我今天真的执行了
这个是从库,没有读业务和其他下游同步,风险可控。但是大家还是要谨慎。我执行这个命令是因为我搜到的菜鸟教程的split命令案例错误导致我生成了大量小文件。没想到大名鼎鼎的菜鸟教程也会有问题,大家还用man或者tldr查看帮助手册吧。
DBA札记
2024/06/03
1260
这条命令有可能断送DBA职业生涯,我今天真的执行了
Swoole 4.4:支持 CURL 协程化
在4.4之前的版本中,Swoole一直不支持CURL协程化,在代码中无法使用curl。由于curl使用了libcurl库实现,无法直接hook它的socket,4.4版本使用Swoole\Coroutine\Http\Client模拟实现了curl的API,并在底层替换了curl_init等函数的C Handler。
桶哥
2019/07/10
1.3K0
擦擦擦
set_robust_list(0x7f0f49370b60, 24) = 0 mmap(NULL, 2097248, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x7f0f31ed3000 nanosleep({0, 100000000}, NULL) = 0 close(3) = 0 clone(child_stack=0, flags=CLONE
waki
2021/12/08
3010
Linux系统编程-进程间通信(mmap内存映射)
前面文章介绍了进程间常用的通信方式: 无名管道和命名管道,这篇文章介绍内存映射,内存映射在多进程访问文件读写的时候非常方便。
DS小龙哥
2022/02/17
1.6K0
Linux系统编程-进程间通信(mmap内存映射)
使用strace分析exp的奇怪问题(r3笔记第41天)
exp算是一个经典的数据导出工具了。对于小数量的表来说,个人还是比较钟爱exp。毕竟expdp还需要配置directory而且还在服务端。exp在数据量小的情况下速度还是很理想的。 关于exp导出的这个问题,已经拖了很久了,自己也排查了各种方法。通过查看wait event,查看exp的debug日志,都没有得出一些很有说服力的内容,今天下定决心来细细琢磨琢磨这个问题。有了一点收获。 之前在测试系统中碰到一个问题,导出一个比较大的分区表,分区数很多,其中有些分区里面没有数据,但是通过exp导出这些没有数据
jeanron100
2018/03/14
7920
文件空间映射mmap()函数(是什么,为什么,怎么用)
1、mmap()函数用来将文件或者设备映射到内存中。 2、mmap的特点是按需调页。最开始只申请vma,并不调真正的页。当对某些页进行引用的时候,会引起一个缺页中断,再将页面调入到内存当中,这样避免了对内存的浪费。
看、未来
2020/08/26
2.6K0
Linux的内存共享映射(mmap和munmap)
       Linux下的进程间通信也可以使用mmap的内存共享映射来实现,mmap的作用就是把磁盘文件的一部分直接映射到进程的内存中,那么进程就可以直接对该内存文件进行操作,mmap也设置了两种机制:共享和私有,如果是共享映射,那么在内存中对文件进行修改,磁盘中对应的文件也会被修改,相反,磁盘中的文件有了修改,内存中的文件也被修改。如果是私有映射,那么内存中的文件是独立的,二者进行修改都不会对对方造成影响。通过这样的内存共享映射就相当于是进程直接对磁盘中的文件进行读写操作一样,那么如果有两个进程来mmap同一个文件,就实现了进程间的通信。磁盘中的文件通过mmap函数来实现映射,然后通过munmap函数取消映射。先来看一下函数的原型:
Ch_Zaqdt
2020/03/05
8.4K0
Linux的内存共享映射(mmap和munmap)
耗时两天,优化失败
在上一篇文章基于线程池的线上服务性能优化中,我们提到了使用线程池进行某个业务功能优化,在上线之后,实时性提高了大概24-30倍样子,基本能够满足实时性要求。在正常运行了几天之后,突然收到了报警,提示popen失败,于是打开了日志,发现有如下提示:
高性能架构探索
2022/08/25
5490
耗时两天,优化失败
【进程间通信】mmap共享存储映射
存储映射I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间(内存)中的一个缓冲区相映射。这样的话,当从缓冲区中取数据,就相当于读文件中的相应的字节,而将数据存入缓冲区,则相应的字节就自动写入文件。这样,就可在不使用read和write函数的情况下,使用地址(指针)完成I/O操作,当然也可以使用内存操作函数strcpy,memcpy等。
mindtechnist
2024/08/08
2440
【进程间通信】mmap共享存储映射
一文读懂 Linux mmap 内存映射
mmap(memory map)即内存映射,用于将一个文件或设备映射到进程的地址空间,或者创建匿名的内存映射。
恋喵大鲤鱼
2024/05/24
6.6K0
一文读懂 Linux mmap 内存映射
相关推荐
10张图22段代码,万字长文带你搞懂虚拟内存模型和malloc内部原理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验