多线程调用同一个函数,该如何处理

多线程调用同一个函数,该如何处理,第1张

应该有必要开启一个新的线程去监视isover线程是否结束,

一来 可以解决线程isover因为执行时间过长导致超时的问题

而来 也能通过监测isover线程的状态来实现线程结束再做其他处理的问题!

未实测,应该不一样。testMethod()是不同对象的成员函数。

如果把testMethod()定义成static

那要看代码怎么写的了,如果是:

A::testmethod(); 应该就一样。

如果是:

(new A())testmethod(); ;应该不一样。

空口说说,你还得相信事实,自己测试吧。

最简单的方法,把这个变量加锁,或者把函数方法加锁,使其同一时间只能被一个线程调用。

但这样牺牲了效率,所以首先你还是得思考以下问题:

1这个变量值会被其他线程改变吗?

如果1的回答是否定的,那么线程之间应该不会受影响

如果是肯定的,思考问题:

2一定要在其他线程中改变这个变量吗?

如果是否定的,考虑使用临时变量或者局部变量代替原变量

如果肯定的,还是考虑加锁吧

暂时想到这么多,欢迎补充:)

是的。根据查询相关公开信息显示,两个线程调用同一个方法时所产生的运行内存会被系统平均分配至两个线程中。java是具有大部分编程语言所共有的一些特征,被特意设计用于互联网的分布式环境。

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)

4WaitForSingleObject函数的返值:

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

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

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

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

TRtlCriticalSection 是一个结构体,在windows单元中定义;

是InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection,

DeleteCriticalSection 等这几个kernel32dll中的临界区 *** 作API的参数;

TCriticalSection是在SyncObjs单元中实现的类,它对上面的那些临界区 *** 作API函数进行了了封装,简化并方便了在Delphi的使用;如TCriticalSectionCreate,TCriticalSectionEnter,

TcriticalSectionLeave等;通过调用上面响应的API函数实现。

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

使用临界区代码如下:

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

var

MyCs:TRTLCriticalSection;

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

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

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

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

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

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

try

//程序代码

finally

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

end;

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

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

if flag then

Begin

Flag:=False;

B;

Flag:=True;

End;

->C

问题成功解决。

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

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

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/13495344.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-09-01
下一篇2025-09-01

发表评论

登录后才能评论

评论列表(0条)

    保存