補充: 多線程編程知識 (多線程是必須逾越過去~~)

本文介绍了多线程编程的基础知识及实现方式,包括通过API创建线程和使用TThread类两种方法,并详细解释了线程同步机制及临界区的应用。

補充: 多線程編程知識  (多線程是必須逾越過去~~)

  1. 示例 :

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to 500000 do
  begin
    Canvas.TextOut(10, 10, IntToStr(i));
    Application.ProcessMessages;  // 一般在比較費時的循環中加入 ProcessMessages,以便可以響應其他消息 ~~ 不是多線程
  end;
end;

  標準線程 :


 a. > 調用 API 創建線程

  function myfun(p : Pointer) : integer;stdcall;
  var
    i : integer;
  begin
    for i := 1 to 500000 do
    begin
      Form1.Canvas.Lock;  //  多線程中必須加鎖
      Form1.Canvas.Textout(100,200,Inttostr(i));
      Form1.Canvas.Unlock;  // 解鎖
    end;
    Result := 0;
  end;
 
  var ID : THandle;

  CreateThread(nil,0,@myfun,nil,0,ID); // 調用 API 創建線程,新建線程執行方法 myfun;
 
  CreateThread 第三個參數是函數指針,新建的線程建立後立即執行該函數,函數執行完後立即銷毀此線程。
  調用的函數必須系統級的,不能屬於某一個類的函數,因此必須加上 stdcall,並且必須具有給定的(參數,返回值)格式,即使用不上也要加上。
  CreateThead還必須接受函數的 THandle。
 
 
  B. > TThread 類

  Type TMyThread = class(TThread)  // TThread 是一個抽像類,必須繼承使用
  protected
     procedure Execute; override;
  end;

  procdure TMyThread.Execute;
  var
    i : Integer;
  begin
    inherited;
    FreeOnTerminate := True;  // 線程執行完後立即結束
    For i :=0 to 500000 then
    begin
      Form1.Canvas.Lock;  //  多線程中必須加鎖
      Form1.Canvas.Textout(100,200,Inttostr(i));
      Form1.Canvas.Unlock;  // 解鎖     
    end;
  end;

procdure TForm1.Button1Click (Sender : TObject);
var
  MyThread : TMyThread;
begin
  MyThread := TMyThread.Create(false);
end;

CreateThread 另外可參見 CreateRemoteThread (建立其它進程中的線程)
CreateThread 返回線程句柄;句柄類似於指針,但句柄只是用來使用對象;有句柄的對象一般為內核對象。
當有多個線程在運行時,系統自動在每個線程中切換執行;線程的數據狀態保持在結構 TContext 中,其相對於一個 CPU寄存器的集合,
可以通過 GetThreadContent 獲得。

線程句柄 and 線程ID : 線程ID 是唯一的;而句柄可以有多個,GetCurrentThread 返回的是一個偽句柄,DuplicateHandle 用來複製一個句柄。
在主線程中 ,GetCurrentThreadID,MainThreadID,MainInstance 返回的是主線程ID。

function CreateThread(
  lpThreadAttributes: Pointer;
  dwStackSize: DWORD;
  lpStartAddress: TFNThreadStartRoutine;
  lpParameter: Pointer;
  dwCreationFlags: DWORD;   // 啟動選項
  var lpThreadId: DWORD
): THandle; stdcall;

  dwCreationFlags : 啟動選項,有2個值:

  0 : 線程建立後立即執行入口函數;

  CREATE_SUSPENDED : 線程建立後掛起等待;
  可用 ResumeThread恢復線程執行; SuspendedThread 再次掛起;

  第四個參數: 線程入口函數的參數 -- lpParameter, 可以指定任何參數。

  第三個參數: lpStartAddress 入口函數指針, DWORD 類型 .
  可以使用 GetExitCodeThread 函數獲得退出碼,即為此返回值.
  ** 入口函數不能為類的方法。

  第二個參數: dwStackSize: DWORD; 分配給線程的堆棧大小。
  第一個參數: lpThreadAttributes : 安全設置, 其指向 TSecurityAttributes結構,
  一般為 nil , 表示沒有訪問限制 .

  線程同步一般使用四個系統內核對象:
  1. 事件 -- CreateEvent;
  2. 互斥 -- CreateMutex;
  3. 信號 -- CreateSemaphore;
  4. 計時器--CreateWaitableTimer;

  比較簡單的同步手段是 CriticalSection (臨界區),其不屬於內核對象,沒有句柄,也不需要跨進程使用。

// 臨界區示例 ****** 
  定義臨界區: CS : TRTLCriticalSection ;
  在線程函數中加入:
  EnterCriticalSection(CS);
  ...
  LeaveCriticalSection(CS);

  FormCreate 中 : InitializeCriticalSection(CS);
  FormDestory中 : DeleteCriticalSectioin(CS);
// 臨界區示例 ******

  等待函數 : WaitForSingleObject

function WaitForSingleObject(
  hHandle: THandle;      {要等待的對象句柄}
  dwMilliseconds: DWORD  {等待的時間--毫秒}
): DWORD; stdcall;  

  返回值如下:
  WAIT_OBJECT_0 : 剛好等著了
  WAIT_TIMEOUT  : 等過了點
  WAIT_ABANDONED: 互斥對象不讓執行

本项目采用C++编程语言结合ROS框架构建了完整的双机械臂控制系统,实现了Gazebo仿真环境下的协同运动模拟,并完成了两台实体UR10工业机器人的联动控制。该毕业设计在答辩环节获得98分的优异成绩,所有程序代码均通过系统性调试验证,保证可直接部署运行。 系统架构包含三个核心模块:基于ROS通信架构的双臂协调控制器、Gazebo物理引擎下的动力学仿真环境、以及真实UR10机器人的硬件接口层。在仿真验证阶段,开发了双臂碰撞检测算法和轨迹规划模块,通过ROS控制包实现了末端执行器的同步轨迹跟踪。硬件集成方面,建立了基于TCP/IP协议的实时通信链路,解决了双机数据同步和运动指令分发等关键技术问题。 本资源适用于自动化、机械电子、人工智能等专业方向的课程实践,可作为高年级课程设计、毕业课题的重要参考案例。系统采用模块化设计理念,控制核心与硬件接口分离架构便于功能扩展,具备工程实践能力的学习者可在现有框架基础上进行二次开发,例如集成视觉感知模块或优化运动规划算法。 项目文档详细记录了环境配置流程、参数调试方法和实验验证数据,特别说明了双机协同作业时的时序同步解决方案。所有功能模块均提供完整的API接口说明,便于使用者快速理解系统架构并进行定制化修改。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值