Delphi关于多线程同步的一些方法
线程是进程内一个相对独立的、可调度的执行单元。一个应用可以有一个主线程,一个主线程可以有多个子线程,子线程还可以有自己的子线程,这样就构成了多线程应用了。由于多个线程往往会同时访问同一块内存区域,频繁的访问这块区域,将会增加产生线程冲突的概率。一旦产生了冲突,将会造成不可预料的结果(比如:该公用区域的值是不可预料的),可见处理线程同步的必要性。
(注意:本文中出现的所有代码都是用DELPHI描述的,调试环境为Windows me ,Delphi 6。其中所涉及的Windows API函数可以从MSDN获得详细的文档。) 首先引用一个实例来引出我们以下的讨论,该实例没有采取任何措施来避免线程冲突。 它的主要过程为:由主线程启动两个线程对letters这个全局变量进行频繁的读写,然后分别把修改的结果显示到ListBox中。由于没有同步这两个线程,使得线程在修改letters时产生了不可预料的结果。 ListBox中的每一行的字母都应该一致,但是上图画线处则不同,这就是线程冲突产生的结果。当两个线程同时访问该共享内存时,一个线程还未对该内存修改完,另一个线程又对该内存进行了修改,由于写值的过程没有被串行化,这样就产生了无效的结果。可见线程同步的重要性。 //定义变量 //进入临界段 //退出临界段 synchronize(addtolist); 好了,重新编译,运行结果如下图所示(略) 下面总结一下Windows常用的几种线程同步技术。 它只能在一个独立的进程或一个独立的应用程序中使用。 使用方法如下: 2. Mutex(互斥对象),是用于串行化访问资源的全局对象。我们首先设置互斥对象,然后访问资源,最后释放互斥对象。在设置互斥对象时,如果另一个线程(或进程)试图设置相同的互斥对象,该线程将会停下来,直到前一个线程(或进程)释放该互斥对象为止。 注意它可以由不同应用程序共享。 使用方法如下: 3. Semaphore(信号量),它与互斥对象相似,但它可以计数。例如可以允许一个给定资源同时同时被三个线程访问。其实Mutex就是最大计数为一的Semaphore。 使用方法如下: 4. 还可以使用Delphi中的TcriticalSection这个VCL对象,它的定义在Syncobjs.pas中。 delphi中多线程同步的一些方法 lpCriticalSection参数是一个TRTLCriticalSection类型的记录,并且是变参。至于TRTLCriticalSection 是如何定义的,这并不重要,因为很少需要查看这个记录中的具体内容。只需要在lpCriticalSection中传递未初始化的记录,InitializeCriticalSection()过程就会填充这个记录。 (**************************************以下尚未整理*********************************) 线程拥有时,它就进入发信号状态。当一个进程要终止时,它就进入发信号状态。dwMilliseconds参数可以设为0,这意味着只检查hHandle参 数指定的对象是否处于发信号状态,而后立即返回。dwMilliseconds参数设为INFINITE,表示如果信号不出现将一直等下去。 种情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态 首先调用WaitForSingleObject()函数的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。当线程调用ReleaseMutex()函数并传 递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。 对象变为发信号状态。这两个函数的详细情况请看Win32 API联机文档。 入要同步的代码。可以用CreateSemaphore()来创建一个信号量对象,其声明如下: nil。 态。当调用WaitForSingleObject()函数(或其他函数)时,此计数值就减1。当调用ReleaseSemaphore()时,此计数值加1。 —————————————————————————————————————————— 主线程中运行,并非线程同步。 内的线程同步,据Richter说是一个记数循环;临界区只能在同一进程内使用;临界区只能无限期等待,不过2k增加了 TryEnterCriticalSection函数实现0时间等待。 这个有名字的内核对象保证系统资源的线程安全性。互斥量是Win32 内核对象,由操作系统负责管理;互斥量可以使用WaitForSingleObject实 现无限等待,0时间等待和任意时间等待。 ,另一个线程在第一个线程处理完之前是不会被执行的。在使用临界区之前,必须使用InitializeCriticalSection()过程来初始化它。 LeaveCriticalSection()后才能被唤醒。 用此名字创建现有互斥对象的附加句柄。 涉及到系统内核要用400~600个时间片。 者,此互斥对象设为不发信号状态。当线程调用ReleaseMutex()函数并传递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对 象重新进入发信号状态。 入要同步的代码。可以用CreateSemaphore()来创建一个信号量对象, 计数加1; 情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态; 个TCriticalSection全局的实例。TcriticalSection有两个方法,Acquire(阻止其他线程执行该区域)和Release(取消阻止) 后,线程调用Release方法,让其他线程也可以通过调用Acquire来使用这块全局内存。 例如:LockXY是一个全局的Critical区变量。任何一个访问全局X, Y的变量的线程,在访问前,都必须使用Acquire 界对象)。 之外建立这个对象)。具体同步的时候使用Lock和Unlock即可。 INFINITE) unlock的时候只需要ReleaseMutex(mutexhandle);即可。 子的, 你可以依靠这一点完成互斥的方法. 对于能够产生全局名称的方法能够可以在进程间同步上(如互斥对象), 也可以用在线程间同步上;不 能够产生全局名称的方法(如临界区)只能用在线程间同步上. |
转载于:https://www.cnblogs.com/bbinking/archive/2010/03/10/1682802.html
Delphi关于多线程同步的一些方法相关推荐
- java多线程同步5种方法
一.引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊.闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会 ...
- DELPHI 多线程同步几种方法
DELPHI 多线程(TThread类的实现) DELPHI 多线程(TThread类的实现) 之前学习了用API实现,让我们再学习下用DELPHI的TThread类. 先新建一个普通的工程,再新建一 ...
- Delphi实现多线程
线程是进程内一个相对独立的.可调度的执行单元.一个应用可以有一个主线程,一个主线程可以有多个子线程,子线程还可以有自己的子线程,这样就构成了多线程应用了.由于多个线程往往会同时访问同一块内存区域,频繁 ...
- 秒杀多线程第十二篇 多线程同步内功心法——PV操作上
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...
- 多线程面试题系列(12):多线程同步内功心法——PV操作上
上面的文章讲解了在Windows系统下实现多线程同步互斥的方法,为了提高在实际问题中分析和思考多个线程之间同步互斥问题的能力,接下来将讲解PV操作,这也是操作系统中的重点和难点.本文将会先简要介绍下P ...
- Delphi中多线程用Synchronize实现VCL数据同步显示
概述: VCL实现同步的另一种方法就是调用线程类的Synchronize的过程,此过程需要一个无参数的procedure,故在此procedure中无法传递参数值,但可以通过类的成员来实现.在类的Ex ...
- Delphi中实现多线程同步查询
优秀的数据库应用应当充分考虑数据库访问的速度问题.通常可以通过优化数据库.优化 查询语句.分页查询等途径收到明显的效果.即使是这样,也不可避免地会在查询时闪现一个带有 SQL符号的沙漏,即鼠标变成了查 ...
- 从C++20 shared_ptr移除unique()方法浅析多线程同步
@[TOC](从C++20 shared_ptr移除unique()方法浅析多线程同步) std::shared_ptr的unique()方法做了什么事情? unique()作为std::shared ...
- C++实现多线程及其三种方法实现多线程同步
1.调用windows API实现多线程 #include "stdafx.h" #include <windows.h> #include <stdio.h&g ...
最新文章
- 关于交换机SVI(转)
- 撒列实现关键字过虑二(附源码)
- 机器学习中用来防止过拟合的方法有哪些?
- spring发展历程
- python怎么安装开发版_python - easy_install的安装和使用
- 搭建LAMP环境的过程详细总结
- easyui 控制某列显示不显示_baogaiMCU控制OLED显示屏
- python写gui、主体程序必须放进函数里吗_Python学习(二):使用TKinter进行GUI程序设计...
- UVa 208-Firetruck
- MVC创建通用DropdownList
- 实战Swiper:利用Swiper制作手机新闻界面
- ubuntu 14.04中安装Jenkins
- 3A游戏制作人员职位及部分职位要求
- win7虚拟机无法读取U盘或密钥常见解决方法
- 使用Falco检测Kubernetes安全问题简介
- 华为机试---Word Maze迷宫游戏
- 宜信CEO唐宁对话英伟达机器学习总监Animashree:AI如何影响人类
- 主流搜索引擎蜘蛛的IP地址网段整理
- CUDA——Python基础与实现
- 电源上的sense什么意思_开关电源基本术语
热门文章
- python调用simulink_使用Python从dbc文件中提取simulink建模数据定义
- 聚集索引和非聚集索引的区别_武汉无疫情小区居民可在小区内非聚集性个人活动...
- java obix_obix协议在java中的配置和使用详解
- eclipse查看git地址_gitamp;github的入门实战
- win10分辨率不能调整_Win10系统分辨率不能修改怎么办?屏幕分辨率的调节方法...
- arcgis导入excel字段不显示_ArcGIS从excel中导入坐标出现空白无法选择字段
- 433M无线串口E30-TTL-100在农业物联网上的应用
- LoRa、蓝牙、技术在电子显示牌上的应用
- 物联网设备的互操作性问题探讨
- jsp mysql论坛_使用SSM和ajax做一个简易的论坛-01(简介和建表)