delphi多线程互斥,用多线程怎么解决同一时间内调用同一函数 Delphi是编程工具,还是编程语言?

Delphi\u7528\u7684\u662f\u4ec0\u4e48\u7f16\u7a0b\u8bed\u8a00?

Delphi \u65e9\u7248\u672c \u4f7f\u7528Object Pascal
Delphi \u9ad8\u7248\u672c\uff0c\u4f7f\u7528Delphi\u8bed\u8a00

Object Pascal\u662fBorland\u5bf9Pascal\u8bed\u8a00\u7684\u6539\u8fdb
\u6bcf\u4e00\u6b21Delphi\u7684\u5347\u7ea7\uff0c\u90fd\u4f1a\u5e26\u6765\u5bf9Object Pascal\u7684\u6539\u8fdb
\u5728Delphi\u9ad8\u7248\u672c\uff0c\u76f4\u63a5\u79f0\u4e4b\u4e3aDelphi\u8bed\u8a00

\u73b0\u5728Delphi\u4e0d\u53ea\u662f\u4e00\u4e2a\u8bed\u8a00\uff0c\u4e00\u4e2a\u5f00\u53d1\u5de5\u5177\uff0c\u5728Codegear\uff0cDelphi\u5df2\u7ecf\u662f\u4e00\u4e2a\u4ea7\u54c1\u7ebf\u540d\u4e86
\u6bd4\u5982Delphi for php\uff0c\u6839\u672c\u548cDelphi\u5f00\u53d1\u5de5\u5177\u6ca1\u6709\u5173\u7cfb

\u53ef\u4ee5\u8bf4\u662f\u7f16\u7a0b\u5de5\u5177\uff0c\u4e5f\u53ef\u4ee5\u8bf4\u662f\u7f16\u7a0b\u8bed\u8a00\uff0c
delphi\u662f\u4ecepascal\u6269\u5c55\u800c\u6765\u7684\u9762\u5411\u5bf9\u8c61\u7684\u8bed\u8a00
\u53ea\u6709borland\u516c\u53f8\u7684delphi\u8f6f\u4ef6\u53ef\u4ee5\u5f00\u53d1\u3002
\u4e0d\u8fc7\u542c\u8bf4borland\u51c6\u5907\u51fa\u552edelphi2005\uff0c
\u4f30\u8ba1\u6ca1\u8fc7\u591a\u4e45\u8fd9\u95e8\u8bed\u8a00\u5c31\u4f1a\u4ece\u5730\u7403\u4e0a\u6d88\u5931!!!!!!!!!

Delphi同步互斥总结

多个线程同时访问一个共享资源或数据时,需要考虑线程同步,Synchronize()是在一个隐蔽的窗口里运行,如果在这里你的任务很繁忙,你的主窗口会阻塞掉;Synchronize()只是将该线程的代码放到主线程中运行,并非线程同步。
临 界区是一个进程里的所有线程同步的最好办法,他不是系统级的,只是进程级的,也就是说他可能利用进程内的一些标志来保证该进程内的线程同步,据
Richter说是一个记数循环;临界区只能在同一进程内使用;临界区只能无限期等待,不过2k增加了TryEnterCriticalSection函
数实现0时间等待。 互斥则是保证多进程间的线程同步,他是利用系统内核对象来保证同步的。由于系统内核对象可以是有名字的,因此多个
进程间可以利用这个有名字的内核对象保证系统资源的线程安全性。互斥量是Win32
内核对象,由操作系统负责管理;互斥量可以使用WaitForSingleObject实现无限等待,0时间等待和任意时间等待。常见的线程同步方法如下:

1. 临界区

临界区是一种最直接的线程同步方式。所谓临界区,就是一次只能由一个线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在第一个线程处理完之前是不会被执行的。使用方法如下:

//在窗体创建中

InitializeCriticalSection(Critical1)

//在窗体销毁中

DeleteCriticalSection(Critical1)

//在线程中

EnterCriticalSection(Critical1)

……保护的代码

LeaveCriticalSection(Critical1)

2. 互斥

互斥非常类似于临界区,除了两个关键的区别:首先,互斥可用于跨进程的线程同步。其次,互斥能被赋予一个字符串名字,并且通过引用此名字创建现有互斥对象的附加句柄。
临界区与事件对象(比如互斥对象)的最大的区别是在性能上。临界区在没有线程冲突时,要用10 ~
15个时间片,而事件对象由于涉及到系统内核要用400~600个时间片。

Mutex(互斥对象),是用于串行化访问资源的全局对象。我们首先设置互斥对象,然后访问资源,最后释放互斥对象。在设置互斥对象时,如果另一个线程(或进程)试图设置相同的互斥对象,该线程将会停下来,直到前一个线程(或进程)释放该互斥对象为止。注意它可以由不同应用程序共享。使用方法如下:

//在窗体创建中

hMutex:=CreateMutex(nil,false,nil)

//在窗体销毁中

CloseHandle(hMutex)

//在线程中

WaitForSingleObject(hMutex,INFINITE)

……保护的代码

ReleaseMutex(hMutex)

3. 信号量

另一种使线程同步的技术是使用信号量对象。它是在互斥的基础上建立的,但信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。可以用CreateSemaphore()来创建一个信号量对象,

因为只允许一个线程进入要同步的代码,所以信号量的最大计数值(lMaximumCount)要设为1。其实Mutex就是最大计数为一的Semaphore。使用方法如下:

//在窗体创建中

hSemaphore:= CreateSemaphore(nil,lInitialCount,lMaximumCount,lpName)

//在窗体销毁中

CloseHandle(hSemaphore)

//在线程中

WaitForSingleObject(hSemaphore,INFINITE)

……保护的代码

ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount)

4.WaitForSingleObject函数的返值:

WAIT_ABANDONED指定的对象是互斥对象,并且拥有这个互斥对象的线程在没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态;

WAIT_OBJECT_0 指定的对象处于发信号状态;

WAIT_TIMEOUT等待的时间已过,对象仍然是非发信号状态;

Delphi 常用的临界区对象TCriticalSection(Delphi) 、TRtlCriticalSection

TRtlCriticalSection 是一个结构体,在windows单元中定义;
是InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection,
DeleteCriticalSection 等这几个kernel32.dll中的临界区操作API的参数;

TCriticalSection是在SyncObjs单元中实现的类,它对上面的那些临界区操作API函数进行了了封装,简化并方便了在Delphi的使用;如TCriticalSection.Create,TCriticalSection.Enter,
TcriticalSection.Leave等;通过调用上面响应的API函数实现。

线程同步的多种办法中,使用临界区最简单,也是效率最高的办法(CPU占用时间最少)

使用临界区代码如下:

先声明一个TRTLCriticalSection类型的全局变量

var

MyCs:TRTLCriticalSection;

在程序开始或建立线程之前,初始化

InitializeCriticalSection(MyCs);//初始化临界区

在程序结束或所有线程结束后,删除它

DeleteCriticalSection(MyCs);//删除临界区

再在线程中要同步的地方加入

EnterCriticalSection(MyCs); //进入临界区

try

//程序代码

finally

LeaveCriticalSection(MyCs); //离开临界区

end;

补充今天遇到的关于Application.ProcessMessages同步的问题:有一个函数Fn按执行顺序可分为A->B->C

3大块,其中B块有要绘制各种窗口界面的操作很复杂且耗时较长,并且里面用到了Application.ProcessMessages,程序运行测试时发现如果在Fn执行B绘制窗口的过程没结束时又调用Fn函数去绘制其它窗口就可能会导致程序崩溃,一开始尝试用TcriticalSection变量解决,完全没用,最后用增加一个全局变量的方法解决:定义一个全局Boolean型变量flag,设定初始值为True,改造Fn函数的逻辑为A->
if flag then

Begin

Flag:=False;

B;

Flag:=True;

End;

->C


问题成功解决。

顺便总结Application.ProcessMessages的作用:运行一个非常耗时的循环,那么在这个循环结束前,程序可能不会响应任何事件,按钮没有反应,程序设置无法绘制窗体,看上去就如同死了一样,这有时不是很方便,例如于终止循环的机会都没有了,又不想使用多线程时,这时你就可以在循环中加上这么一句,每次程序运行到这句时,程序就会让系统响应一下消息,从而使你有机会按按钮,窗体有机会绘制。所起作用类似于VB中DoEvent方法.

调用ProcessMessages来使应用程序处于消息队列能够进行消息处理,ProcessMessages将Windows消息进行循环轮转,直至消息为空,然后将控制返回给应用程序。

注示:仅在应用程序调用ProcessMessages时勿略消息进程效果,而并非在其他应用程序中。在冗长的操作中,调用ProcessMessages周期性使得应用程序对画笔或其他信息产生回应。

ProcessMessages不充许应该程序空闲,而HandleMessage则然.使用ProcessMessages一定要保证相关代码是可重入的,如果实在不行也可按我上面的方法实现同步。



  • delphi澶氱嚎绋嬩簰鏂,鐢ㄥ绾跨▼鎬庝箞瑙e喅鍚屼竴鏃堕棿鍐呰皟鐢ㄥ悓涓鍑芥暟
    绛旓細浜掓枼鍒欐槸淇濊瘉澶氳繘绋嬮棿鐨勭嚎绋嬪悓姝ワ紝浠栨槸鍒╃敤绯荤粺鍐呮牳瀵硅薄鏉ヤ繚璇佸悓姝ョ殑銆傜敱浜庣郴缁熷唴鏍稿璞″彲浠ユ槸鏈夊悕瀛楃殑锛屽洜姝ゅ涓 杩涚▼闂村彲浠ュ埄鐢ㄨ繖涓湁鍚嶅瓧鐨勫唴鏍稿璞′繚璇佺郴缁熻祫婧愮殑绾跨▼瀹夊叏鎬с備簰鏂ラ噺鏄疻in32 鍐呮牳瀵硅薄锛岀敱鎿嶄綔绯荤粺璐熻矗绠$悊锛涗簰鏂ラ噺鍙互浣跨敤WaitForSingleObject瀹炵幇鏃犻檺绛夊緟锛0鏃堕棿绛夊緟鍜屼换鎰忔椂闂寸瓑寰呫傚父瑙佺殑绾跨▼...
  • delphi澶氱嚎绋嬩簰鏂,鐢ㄥ绾跨▼鎬庝箞瑙e喅鍚屼竴鏃堕棿鍐呰皟鐢ㄥ悓涓鍑芥暟
    绛旓細浣犲澶氱嚎绋鐨勭悊瑙e彲鑳芥湁鍋忥紝澶氱嚎绋嬫槸鍏佽鍦ㄥ悓涓鏃堕棿鍐呰皟鐢ㄥ悓涓鍑芥暟鐨勩傚湪澶氱嚎绋嬬紪绋嬩腑瑕佹敞鎰忚В鍐崇殑闂锛屾槸闃叉瀵瑰叏灞瀵硅薄鎴栧彉閲忕殑鍚屾椂璁块棶銆備富瑕佹湁涓夌绛栫暐锛岀涓锛屽姞閿佸璞★紱绗簩锛屼娇鐢ㄤ复鐣屽尯 绗笁锛屼娇鐢ㄥ璇绘帓瀹冨啓鐨勫悓姝ユ満鍒躲傝缁嗚鏄庯紝delphi鐨甯姪鏂囨。涓兘鏈夈
  • Delphi 7 澶氱嚎绋澶勭悊,鍚屾,浜掓枼,浜掓枼淇″彿閲,娑堟伅寰幆
    绛旓細棣栧厛浣犺鎼炴竻妤氫綘鐨勮繖涓绠楄兘澶熷苟琛岃绠椾笉锛屽鏋滄槸涓涓绠楄緭鍏ュ繀椤荤瓑寰呭彟澶栦竴涓绠楃殑杈撳嚭锛岄偅涔堝氨瑕佽冭檻杩欎釜澶氱嚎绋鐨勫繀瑕佷簡銆傚湪涓荤嚎绋嬩腑璁块棶绾跨▼涓殑鏁版嵁锛岀敤娑堟伅鏄渶濂界殑锛屼絾鏄笉寤鸿鍦ㄤ富绾跨▼淇敼绾跨▼涓殑鏁版嵁锛屼粎闄愪簬璇诲彇銆傜敤娑堟伅姣旇緝瀹夊叏锛岀敤鍚屾鏂瑰紡鏈夊彲鑳介犳垚姝绘満鐨勯棶棰樸
  • delphi 澶氱嚎绋缂栫▼闂
    绛旓細1.鍦ㄦ洿鏂癡CL鎺т欢鐨勬椂鍊欎娇鐢⊿ynchronize.2.濡傛灉绾跨▼鍐呭畾涔変簡鍏ㄥ眬鍙橀噺,濡傛灉鎯充慨鏀瑰畠鐨勮瘽,涓鑸父鐢ㄤ复鐣,濡傛灉鏄杩涚▼鏂瑰紡鍚屾鐨勮瘽浣跨敤浜掓枼绛...3.浣犳墍璇寸殑浣跨敤synchonrize鍜屼笉浣跨敤synchronize缁撴灉涓鏍,娌℃湁浠涔堝尯鍒.!杩欐槸鍦ㄥ崟涓嚎绋嬩腑娌℃湁鍙戠幇闂,濡傛灉澶氫釜绾跨▼鍚屾椂杩愯姝ゆ浠g爜灏变細鍑虹幇鍐呭瓨鍐欏叆鍜岃鍙栭敊璇簡!
  • delphi 澶氱嚎绋 ,姹傚府蹇
    绛旓細鍥犱负绾跨▼涓嶅悓姝ラ棶棰樸侼ewThread:=TTestThread.Create(False);绾跨▼杩樻病鏈夌嚎鏉燂紝灏辨墽琛屽埌浜 Edit1.Text :=IntToStr(Answer);鎵浠ヤ负0 鐢ㄥ涓嬩唬鐮佽瘯璇曪細unit Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;type TTestThread=class(T...
  • 鎵╁睍Delphi鐨勭嚎绋鍚屾瀵硅薄
    绛旓細鍦ㄧ紪鍐澶氱嚎绋搴旂敤绋嬪簭鏃 鏈閲嶈鐨勬槸鎺у埗濂界嚎绋嬮棿鐨勫悓姝ヨ祫婧愯闂 浠ヤ繚璇佺嚎绋嬬殑瀹夊叏杩愯 Win API鎻愪緵浜嗕竴缁勫悓姝ュ璞 濡 淇″彿鐏(Semaphore) 浜掓枼锛圡utex锛 涓寸晫鍖猴紙CriticalSection锛夊拰浜嬩欢(Event)绛 鐢ㄦ潵瑙e喅杩欎釜闂 Delphi鍒嗗埆灏嗕簨浠跺璞″拰涓寸晫鍖哄璞″皝瑁呬负Tevent瀵硅薄鍜孴critialSection瀵硅薄 浣垮緱杩欎袱涓璞...
  • DELPHI鐨勫绾跨▼鍔熻兘鏈夋病鏈塁PU鏄笉鍏煎鐨勫晩
    绛旓細2锛夐氫俊锛氳繘绋嬮棿閫氫俊IPC锛岀嚎绋嬮棿鍙互鐩存帴璇诲啓杩涚▼鏁版嵁娈碉紙濡傚叏灞鍙橀噺锛夋潵杩涜閫氫俊鈥斺旈渶瑕佽繘绋嬪悓姝ュ拰浜掓枼鎵嬫鐨勮緟鍔╋紝浠ヤ繚璇佹暟鎹殑涓鑷存с3锛夎皟搴﹀拰鍒囨崲锛氱嚎绋嬩笂涓嬫枃鍒囨崲姣旇繘绋嬩笂涓嬫枃鍒囨崲瑕佸揩寰楀銆4锛夊湪澶氱嚎绋OS涓紝杩涚▼涓嶆槸涓涓彲鎵ц鐨勫疄浣撱傚湪璁$畻鏈烘搷浣滅郴缁熶腑,杞婚噺绾ц繘绋嬶紙LWP锛夋槸涓绉嶅疄鐜板浠诲姟鐨...
  • delphi涓,璁╃▼搴忓彧杩愯涓娆$殑鏂规硶[1]
    绛旓細涓嬮潰鏄Delphi鐗堢殑瑙e喅鏂规硶 (鏂规硶涓)鍒╃敤浜掓枼瀵硅薄寮鍙戣繃澶氱嚎绋杞欢鐨勫彲鑳介兘浣跨敤杩囦簰鏂ュ璞 瀹冨父琚敤鍋氱嚎绋嬮棿鍚屾鐨勬妧鏈墜娈 绠瑕佺殑鎻愪竴涓嬩簰鏂ュ璞 浜掓枼瀵硅薄鎶婄涓娆″缓绔嬪畠鐨勭▼搴忎綔涓轰富绋嬪簭 杩欐牱鍙敤妫娴嬩簰鏂ュ璞℃槸鍚﹀凡缁忔湁涓荤▼搴忓氨鍒ゆ柇绋嬪簭鏄惁宸茬粡杩愯杩 杩欓噷闇瑕佹秹鍙婂埌涓涓猘pi鍑芥暟 WaitForSingleObject 璇ュ嚱鏁...
  • Delphi绋嬪簭绐楀彛濡備綍婵娲昏嚜宸卞拰鍙繍琛屼竴涓疄渚
    绛旓細1. hAppMutex := CreateMutex(nil, false, '');//鏈濂界敤GUID ,鍥犱负Mutex涓鸿法杩涚▼鐨勶紝涓囦竴鍦ㄥ悓涓鏈嶅姟鍣ㄤ笂杩愯鍙︿竴涓▼搴忥紝鏄敤Mutex鏉ュ疄鐜澶氱嚎绋嬩簰鏂鐨勶紝浣犵殑绋嬪簭灏辫繍琛屼笉浜嗕簡锛 2. 婵娲绘煇绐椾綋鍙傝F1
  • delphi WaitForSingleObject 鍑芥暟 鐢ㄦ硶
    绛旓細浣嗘槸濡傛灉浣犳妸ReleaseMutex(HMux)璇彞鏀惧湪绾跨▼鎵ц浠g爜涓棿鐨勮瘽锛岀涓涓嚎绋嬫病鎵ц瀹屽氨浼氶噴鏀浜掓枼瀵硅薄锛岀劧鍚庣浜屼釜绾跨▼灏卞湪绗竴涓嚎绋嬫病鎵ц瀹岀殑鎯呭喌涓嬭婵娲伙紝濡傛灉绗竴涓嚎绋嬬殑鍏叡璧勬簮杩樻病閲婃斁锛岀浜屼釜绾跨▼浜夋姠鍏叡璧勬簮灏变細鍑虹幇闂锛堝彂鐢熸閿佹垨鐩存帴鎶ラ敊锛夛紒甯屾湜鎴戠殑鍥炵瓟鑳藉浣犳湁鎵甯姪锛侊紒锛
  • 扩展阅读:英特尔cpu针脚对照表 ... 主板和cpu对照一览表 ... 电脑8核和12核哪个好 ... cpu几核几线程最好 ... 为什么不建议用多线程 ... 为什么不建议用线程池 ... 深度系统deepin官网 ... 多线程同步互斥的方法 ... idm为什么不建议拉满线程 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网