ros2 launch文件編寫詳解

一個完整的簡單的launch文件配置過程

1.編寫launch文件

2.配置package.xml

3.配置setup.py(python包)

4.配置CMakeList(C++包)

5.編譯+運行

# 在 ROS 2 的 Python 啟動文件中,這些導入語句用于引入各類啟動模塊,以構建和配置節點啟動流程
from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='turtlesim',namespace='turtlesim1',executable='turtlesim_node',name='sim'),Node(package='turtlesim',namespace='turtlesim2',executable='turtlesim_node',name='sim'),Node(package='turtlesim',executable='mimic',name='mimic',remappings=[('/input/pose', '/turtlesim1/turtle1/pose'),('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),])])

package.xml加入以下內容:?

<exec_depend>ros2launch</exec_depend>

CMakeList:??to the end of the file (but before?ament_package()).

# Install launch files.
install(DIRECTORYlaunchDESTINATION share/${PROJECT_NAME}/
)

package.list:

import os
from glob import glob
# Other imports ...package_name = 'py_launch_example'setup(# Other parameters ...data_files=[# ... Other data files# Include all launch files.(os.path.join('share', package_name, 'launch'), glob('launch/*'))]
)

?

替換表達式

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.substitutions import FindPackageSharedef generate_launch_description():colors = {'background_r': '200'}return LaunchDescription([# 使用PathJoinSubstitution和FindPackageShare動態構建啟動文件路徑IncludeLaunchDescription(PathJoinSubstitution([FindPackageShare('launch_tutorial'),'launch','example_substitutions.launch.py']),# 傳遞給被包含啟動文件的參數launch_arguments={'turtlesim_ns': 'turtlesim2','use_provided_red': 'True','new_background_r': colors['background_r'],}.items())])

在 Python 中,.items()?是字典(dict)對象的一個方法,用于將字典轉換為可迭代的鍵值對元組列表。

又如:

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess, TimerAction
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch_ros.actions import Nodedef generate_launch_description():# turtlesim_ns = LaunchConfiguration('turtlesim_ns')use_provided_red = LaunchConfiguration('use_provided_red')new_background_r = LaunchConfiguration('new_background_r')return LaunchDescription([DeclareLaunchArgument('turtlesim_ns',default_value='turtlesim1'),DeclareLaunchArgument('use_provided_red',default_value='False'),DeclareLaunchArgument('new_background_r',default_value='200'),Node(package='turtlesim',namespace=turtlesim_ns,executable='turtlesim_node',name='sim'),ExecuteProcess(cmd=[['ros2 service call ',turtlesim_ns,'/spawn ','turtlesim/srv/Spawn ','"{x: 2, y: 2, theta: 0.2}"']],shell=True),ExecuteProcess(cmd=[['ros2 param set ',turtlesim_ns,'/sim background_r ','120']],shell=True),TimerAction(period=2.0,actions=[ExecuteProcess(condition=IfCondition(PythonExpression([new_background_r,' == 200',' and ',use_provided_red])),cmd=[['ros2 param set ',turtlesim_ns,'/sim background_r ',new_background_r]],shell=True),],)])

為什么需要 LaunchConfiguration?

簡單說,LaunchConfiguration就像一個 “參數占位符”。當你在 Launch 文件中聲明了一個啟動參數(比如DeclareLaunchArgument('turtlesim_ns')),LaunchConfiguration可以引用這個參數的值,讓你在后續的節點、動作配置中動態使用它,而不用寫死具體數值。

比如你聲明了一個參數background_r,默認值為 200,但用戶啟動時可能會通過命令行修改為 255。LaunchConfiguration('background_r')就能自動獲取用戶輸入的最新值,無需修改 Launch 文件代碼。

命令行進程調用:

ExecuteProcess(cmd=[['ros2 param set ',turtlesim_ns,'/sim background_r ','120']],shell=True),

條件執行:

TimerAction(period=2.0,actions=[ExecuteProcess(condition=IfCondition(PythonExpression([new_background_r,' == 200',' and ',use_provided_red])),cmd=[['ros2 param set ',turtlesim_ns,'/sim background_r ',new_background_r]],shell=True),],)

格式:?

TimerAction(period = ....  # 多少時間后actions =[ExecuteProcess(condition = IfCondition(......  # 具體條件),cmd = [ [........... # 命令行指令]],shell = True),],)

這段代碼的作用是:在啟動后 2 秒,檢查特定條件是否滿足,如果滿足則執行一條 ROS 2 命令修改 turtlesim 模擬器的背景紅色值

ROS 2 中的事件處理器(Event Handlers)使用示例?


from launch import LaunchDescription
from launch.actions import (DeclareLaunchArgument,EmitEvent,ExecuteProcess,LogInfo,RegisterEventHandler,TimerAction
)
from launch.conditions import IfCondition
from launch.event_handlers import (OnExecutionComplete,OnProcessExit,OnProcessIO,OnProcessStart,OnShutdown
)
from launch.events import Shutdown
from launch.substitutions import (EnvironmentVariable,FindExecutable,LaunchConfiguration,LocalSubstitution,PythonExpression
)
from launch_ros.actions import Nodedef generate_launch_description():turtlesim_ns = LaunchConfiguration('turtlesim_ns')use_provided_red = LaunchConfiguration('use_provided_red')new_background_r = LaunchConfiguration('new_background_r')turtlesim_ns_launch_arg = DeclareLaunchArgument('turtlesim_ns',default_value='turtlesim1')use_provided_red_launch_arg = DeclareLaunchArgument('use_provided_red',default_value='False')new_background_r_launch_arg = DeclareLaunchArgument('new_background_r',default_value='200')turtlesim_node = Node(package='turtlesim',namespace=turtlesim_ns,executable='turtlesim_node',name='sim')spawn_turtle = ExecuteProcess(cmd=[[FindExecutable(name='ros2'),' service call ',turtlesim_ns,'/spawn ','turtlesim/srv/Spawn ','"{x: 2, y: 2, theta: 0.2}"']],shell=True)change_background_r = ExecuteProcess(cmd=[[FindExecutable(name='ros2'),' param set ',turtlesim_ns,'/sim background_r ','120']],shell=True)change_background_r_conditioned = ExecuteProcess(condition=IfCondition(PythonExpression([new_background_r,' == 200',' and ',use_provided_red])),cmd=[[FindExecutable(name='ros2'),' param set ',turtlesim_ns,'/sim background_r ',new_background_r]],shell=True)return LaunchDescription([turtlesim_ns_launch_arg,use_provided_red_launch_arg,new_background_r_launch_arg,turtlesim_node,RegisterEventHandler(OnProcessStart(target_action=turtlesim_node,on_start=[LogInfo(msg='Turtlesim started, spawning turtle'),spawn_turtle])),RegisterEventHandler(OnProcessIO(target_action=spawn_turtle,on_stdout=lambda event: LogInfo(msg='Spawn request says "{}"'.format(event.text.decode().strip())))),RegisterEventHandler(OnExecutionComplete(target_action=spawn_turtle,on_completion=[LogInfo(msg='Spawn finished'),change_background_r,TimerAction(period=2.0,actions=[change_background_r_conditioned],)])),RegisterEventHandler(OnProcessExit(target_action=turtlesim_node,on_exit=[LogInfo(msg=(EnvironmentVariable(name='USER'),' closed the turtlesim window')),EmitEvent(event=Shutdown(reason='Window closed'))])),RegisterEventHandler(OnShutdown(on_shutdown=[LogInfo(msg=['Launch was asked to shutdown: ', LocalSubstitution('event.reason')])])),])

?詳解:

這個啟動文件創建了一個 turtlesim 模擬器,并實現了以下功能:

  1. 啟動 turtlesim 節點后,自動生成一只新烏龜
  2. 捕獲生成烏龜的服務響應并打印日志
  3. 烏龜生成完成后,修改模擬器背景顏色
  4. 2 秒后,根據參數條件再次修改背景顏色
  5. 當 turtlesim 窗口關閉時,自動終止整個啟動過程
  6. 捕獲系統關閉事件并打印關閉原因
1.節點與命令定義
turtlesim_node = Node(package='turtlesim',namespace=turtlesim_ns,executable='turtlesim_node',name='sim'
)
spawn_turtle = ExecuteProcess(...)  # 生成烏龜的服務調用
change_background_r = ExecuteProcess(...)  # 修改背景顏色的命令
change_background_r_conditioned = ExecuteProcess(...)  # 條件性修改背景顏色

這些組件定義了要執行的基本操作,但它們的執行時機由事件處理器控制。

2.事件處理器注冊
RegisterEventHandler(OnProcessStart(target_action=turtlesim_node,on_start=[LogInfo(...), spawn_turtle])
)
  • OnProcessStart:當turtlesim_node啟動時,觸發生成烏龜的命令。

RegisterEventHandler(OnProcessIO(target_action=spawn_turtle,on_stdout=lambda event: LogInfo(...))
)
  • OnProcessIO:捕獲spawn_turtle命令的標準輸出,提取服務響應信息。

當執行spawn_turtle命令(即調用turtlesim/srv/Spawn服務)時,服務響應會通過標準輸出返回。例如:

ros2 service call /turtlesim1/spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2}"

服務成功響應后,控制臺會打印:

[INFO] [launch]: Spawn request says "Created turtle [turtle2]"

這表明新烏龜已成功生成,并且名稱為turtle2

RegisterEventHandler(OnExecutionComplete(target_action=spawn_turtle,on_completion=[LogInfo(...), change_background_r, TimerAction(...)])
)
  • OnExecutionComplete:當spawn_turtle命令完成后,修改背景顏色,并設置一個 2 秒后的延遲動作。

RegisterEventHandler(OnProcessExit(target_action=turtlesim_node,on_exit=[LogInfo(...), EmitEvent(event=Shutdown(...))])
)
  • OnProcessExit:當turtlesim_node退出時,觸發系統關閉事件。

RegisterEventHandler(OnShutdown(on_shutdown=[LogInfo(...)])
)
  • OnShutdown:捕獲系統關閉事件,打印關閉原因。
3.編譯執行:?
ros2 launch launch_tutorial example_event_handlers.launch.py turtlesim_ns:='turtlesim3' use_provided_red:='True' new_background_r:=200

管理大型工程

頂層管理:

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.substitutions import FindPackageSharedef generate_launch_description():launch_dir = PathJoinSubstitution([FindPackageShare('launch_tutorial'), 'launch'])return LaunchDescription([IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'turtlesim_world_1.launch.py'])),IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'turtlesim_world_2.launch.py'])),IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'broadcaster_listener.launch.py']),launch_arguments={'target_frame': 'carrot1'}.items()),IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'mimic.launch.py'])),IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'fixed_broadcaster.launch.py'])),IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'turtlesim_rviz.launch.py'])),])

在launch文件設置參數:

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([DeclareLaunchArgument('background_r', default_value='0'),DeclareLaunchArgument('background_g', default_value='84'),DeclareLaunchArgument('background_b', default_value='122'),Node(package='turtlesim',executable='turtlesim_node',name='sim',parameters=[{'background_r': LaunchConfiguration('background_r'),'background_g': LaunchConfiguration('background_g'),'background_b': LaunchConfiguration('background_b'),}]),])

通過YAML文件設置參數:

from launch import LaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageSharedef generate_launch_description():return LaunchDescription([Node(package='turtlesim',executable='turtlesim_node',namespace='turtlesim2',name='sim',parameters=[PathJoinSubstitution([FindPackageShare('launch_tutorial'), 'config', 'turtlesim.yaml'])],),])

/turtlesim2/sim:ros__parameters:background_b: 255background_g: 86background_r: 150

整個/turtlesim2/sim代表的是 “位于turtlesim2命名空間下、名為simturtlesim節點”,其后的ros__parameters則是該節點的具體參數配置(如背景色的 RGB 值)

命名空間 :

當啟動文件需要包含大量節點時,手動為每個節點單獨設置命名空間會變得繁瑣且易出錯。PushRosNamespace?提供了一種更優雅的解決方案,讓你可以為一組節點批量設置命名空間。

首先remove the?namespace='turtlesim2'?line from the?turtlesim_world_2.launch.py?。然后按照以下修改:

from launch.actions import GroupAction
from launch_ros.actions import PushRosNamespace...GroupAction(actions=[PushROSNamespace('turtlesim2'),IncludeLaunchDescription(PathJoinSubstitution([launch_dir, 'turtlesim_world_2.launch.py'])),]),

那么在turtlesim_world_2.launch.py中的每一個節點都有一個turtlesim2前綴的命令空間。

節點復用

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfigurationfrom launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([DeclareLaunchArgument('target_frame', default_value='turtle1',description='Target frame name.',),Node(package='turtle_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster1',parameters=[{'turtlename': 'turtle1'}],),Node(package='turtle_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster2',parameters=[{'turtlename': 'turtle2'}],),Node(package='turtle_tf2_py',executable='turtle_tf2_listener',name='listener',parameters=[{'target_frame': LaunchConfiguration('target_frame')}],),])

?話題重映射

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='turtlesim',executable='mimic',name='mimic',remappings=[('/input/pose', '/turtle2/pose'),('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),])])

?啟動rviz,并按照文件配置:

from launch import LaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageSharedef generate_launch_description():return LaunchDescription([Node(package='rviz2',executable='rviz2',name='rviz2',arguments=['-d', PathJoinSubstitution([FindPackageShare('turtle_tf2_py'), 'rviz', 'turtle_rviz.rviz'])],),])

動態配置節點名:

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import EnvironmentVariable, LaunchConfiguration
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([DeclareLaunchArgument('node_prefix',default_value=[EnvironmentVariable('USER'), '_'],description='prefix for node name'),Node(package='turtle_tf2_py',executable='fixed_frame_tf2_broadcaster',name=[LaunchConfiguration('node_prefix'), 'fixed_broadcaster'],),])
  1. 聲明一個啟動參數node_prefix,默認值為當前系統用戶的用戶名加上下劃線(例如:doubao_)
  2. 啟動一個節點,節點名稱由node_prefix和固定后綴fixed_broadcaster組成(例如:doubao_fixed_broadcaster)

更新setup.py:

import os
from glob import glob
from setuptools import setup
...data_files=[...(os.path.join('share', package_name, 'launch'),glob('launch/*')),(os.path.join('share', package_name, 'config'),glob('config/*.yaml')),(os.path.join('share', package_name, 'rviz'),glob('config/*.rviz')),],

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916864.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916864.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916864.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QT中QTableView+Model+Delegate實現一個demo

一、概述功能: 實現一個查詢學生信息的表格&#xff0c;有學號、性別、年齡、班級和分數共5列&#xff0c;針對最后一列分數實現委托代理&#xff0c;要求能編輯和查看該分數列。QTableView實現視圖展示uiModel負責數據的構造Delegate是委托&#xff0c;可針對某列數據做自定義…

用latex+vscode寫論文

文章目錄 前言 一、下載texlive安裝包 二、安裝texlive 1.安裝 2.配置環境變量 3.檢查是否安裝成功 三、安裝vscode 四、vscode中安裝latex workshop插件 五、創建latex文檔 六、撰寫+編譯+預覽 七、latex workshop常用設置 1.打開設置頁面 2.設置自動保存代碼 3.設置自動編譯代…

監測預警系統:讓園區更高效、更安全、更智能

隨著城市化進程的加快和產業集聚效應的凸顯&#xff0c;園區作為經濟發展的重要載體&#xff0c;其規模不斷擴大&#xff0c;功能日益復雜。在這一背景下&#xff0c;傳統的園區管理模式已難以滿足現代園區高效、安全、智能的運營需求。園區監測預警系統作為一種集成了物聯網、…

分享一個AutoOff定時動作軟件

我們平時在使用電腦的時候有很多需求的功能&#xff0c;比如定時打開程序、定時關閉程序、定時休眠、定時關機等等。如果你也有這樣的需求&#xff0c;那么就需要今天這款軟件。AutoOff定時動作軟件AutoOff這個軟件是一款定時的軟件&#xff0c;軟件大小只有1.1M&#xff0c;而…

RPA軟件推薦:提升企業自動化效率

在數字化轉型浪潮中&#xff0c;機器人流程自動化&#xff08;RPA&#xff09;已成為企業降本增效的核心工具。它通過模擬人類操作&#xff0c;自動化重復性任務&#xff0c;如數據錄入、報表生成和系統集成&#xff0c;顯著提升運營效率。面對眾多RPA軟件&#xff0c;如何選擇…

【Qt】QTime::toString(“hh:mm:ss.zzz“) 顯示亂碼的原因與解決方案

在使用 Qt 編寫計時器程序時&#xff0c;我遇到一個很奇怪的問題&#xff1a;使用 QTime::toString("hh:mm:ss.zzz") 格式化時間后&#xff0c;顯示出來的是一串亂碼&#xff0c;如下所示&#xff1a;本來應該是&#xff1a;但卻顯示了一堆“〇”或奇怪的符號。問題表…

MSVC編譯KDChart過程

MSVC編譯KDChart過程 一、下載KDChart源文件 GitHub源文件 查看文件夾里的INSTALL.txt&#xff0c;可以看到需要CMake編譯。 中文版 以下是使用 CMake 構建系統安裝 KD Chart 的說明。 需要 CMake 3.3 或更高版本。Qt 版本支持&#xff1a;* KD Chart 2.5.0 及以下版本需要…

AI Agent管理后臺原型設計全拆解(附3套可復用素材)

最近在做AI方向的產品&#xff0c;越來越能感受到“智能體”這個概念正在從技術圈走向應用層。無論是內部探索項目&#xff0c;還是外部合作需求&#xff0c;很多場景都會提到Agent、助手、知識庫這些關鍵詞。我們經常討論如何打造一個有用的AI Agent&#xff0c;但實際上&…

ABP VNext + Elastic APM:微服務性能監控

ABP VNext Elastic APM&#xff1a;微服務性能監控 &#x1f680; &#x1f4da;目錄ABP VNext Elastic APM&#xff1a;微服務性能監控 &#x1f680;一、引言 ?架構全景圖 &#x1f3d7;?二、環境與依賴 &#x1f4e6;三、APM 服務器與 Kibana 快速部署 &#x1f433;Doc…

單片機學習筆記.AD/DA(略含有SPI,用的是普中開發板上的XPT2046芯片)

AD/DA基礎知識 硬件電路&#xff1a; 模電運放知識回顧&#xff1a; 虛短&#xff08;Virtual Short&#xff09;定義&#xff1a;運放同相輸入端&#xff08;&#xff09;和反相輸入端&#xff08;-&#xff09;的電位近似相等&#xff0c;即V V-&#xff0c;仿佛兩個輸入端短…

避坑指南:VMware安裝CentOS常見錯誤及完美解決方案

1. 引言 虛擬機允許在同一臺機子上有不同的操作系統&#xff0c;還可以用于搭建實驗環境、軟件測試和兼容性測試等。我是主攻大數據方向的會用到Linux操作系統&#xff0c;所以虛擬機對我來說是很有必要的。我把之前的筆記和安裝包整理了一下&#xff0c;就有了現在這個教程。…

Python爬蟲04_Requests豆瓣電影爬取

一、 爬取豆瓣電影排行榜數據 import requests import json url ‘https://movie.douban.com/j/chart/top_list’ param { ‘type’:‘24’, ‘interval_id’:‘100:90’, ‘action’:‘’, ‘start’:‘0’, #從庫中的第幾部電影去取 ‘limit’:‘20’, } headers { ‘Use…

工業物聯網模塊運營指南?

一、運營目標 工業物聯網模塊運營的核心目標在于通過高效運作,實現提高工業設備運行效率、降低生產成本、推動生產過程智能化管理,進而提升企業的整體競爭力。這一目標是后續所有運營工作的出發點和落腳點,為各項運營環節提供方向指引。 二、關鍵運營環節及做法 (一)設…

9.項目起步(3)

1項目起步-靜態資源初始化 和 Error Lens 安裝圖片資源和樣式資源error lens 安裝2項目起步-scss文件自動導入為什么要自動導入自動導入配置scss變量自動導入$xtxColor: #27ba9b; $helpColor: #e26237; $sucColor: #1dc779; $warnColor: #ffb302; $priceColor: #cf4444;css: {p…

MCP提示詞工程:上下文注入的藝術與科學

MCP提示詞工程&#xff1a;上下文注入的藝術與科學 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特性都是我放飛的蝴蝶…

字節跳動GR-3:可泛化、支持長序列復雜操作任務的機器人操作大模型(技術報告解讀)

1.總結 GR-3 是一個大規模的視覺 - 語言 - 動作&#xff08;VLA&#xff09;模型。它對新物體、新環境以及含抽象概念的新指令展現出較好的泛化能力。此外&#xff0c;GR-3 支持少量人類軌跡數據的高效微調&#xff0c;可快速且經濟地適應新任務。GR-3 在處理長周期和靈巧性任…

713. 乘積小于 K 的子數組

中等 給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回子數組內所有元素的乘積嚴格小于 k 的連續子數組的數目。 示例 1&#xff1a; 輸入&#xff1a;nums [10,5,2,6], k 100 輸出&#xff1a;8 解釋&#xff1a;8 個乘積小于 100 的子數組分別為&#xff1a;[10…

【算法】 SM2、FSRS、SuperMemo算法實現艾賓浩斯記憶曲線,通過以上算法你也可以開發出單詞記憶軟件

有那些算法可以實現艾賓浩斯單詞記憶 用戶: 有那些算法可以實現艾賓浩斯單詞記憶 元寶: 以下是基于 艾賓浩斯遺忘曲線 的智能記憶算法實現方案&#xff0c;結合 間隔重復算法 與 現代機器學習技術&#xff0c;提供從理論到實踐的完整解決方案&#xff1a; 一、核心算法原理 1. …

SQL167 連續簽到領金幣

SQL167 連續簽到領金幣 題目描述 用戶行為日志表 tb_user_log iduidartical_idin_timeout_timesign_in110102021-07-07 10:00:002021-07-07 10:00:091210102021-07-08 10:00:002021-07-08 10:00:091310102021-07-09 10:00:002021-07-09 10:00:42141010 2021-07-10 10:00:00 …

PHP性能優化與高并發處理:從基礎到高級實踐

引言 在當今高流量的互聯網環境中,PHP應用的性能優化變得至關重要。本文將全面探討PHP性能優化的各個層面,從基礎優化技巧到高級并發處理方案,幫助開發者構建高性能的PHP應用。 基礎性能優化 OPcache配置優化 ; php.ini 推薦OPcache配置 [opcache] opcache.enable=1 opc…