3个超高的系统概念问题,请高手解答 ( 积分: 100 )

  • 主题发起人 主题发起人 sunstone
  • 开始时间 开始时间
S

sunstone

Unregistered / Unconfirmed
GUEST, unregistred user!
有三个疑惑,一直未能找到答案,烦请各位大虾答疑解惑:

1.线程方面:
有2个线程:线程A,线程B,还有一个公用单元 unit Common(这个单元中有一个线程A
和线程B共同使用的函数Function C),线程A和线程B都使用了 Unit Common单元,并且
都使用了Function C。
假如系统时间片分配,有这么一种状态:系统给线程A和线程B的两个时间片是相邻的,
而且这时候线程A和线程B都调用了Function C,如果Function C内部处理时间有点长的
化,Function 输出的结果会不会乱,就是线程A和线程B几乎同时运行在Function C内。

我的理解:
我做了一个例子,进行反汇编,发现线程A和线程B的汇编语句都是Call xxxx,call指向的地址是一样的,所以function C 结果肯定会出问题。如何避免这个问题,想了几个解决方案:
在function C函数中使用互斥,信号量等办法,可以解决,但是效率会低点,因为同时只
有一个线程能进入Function C。那好,不如将Function C函数分别放到线程A和线程B的类
中,经反汇编,Call xxxx 的地址不一样了,结果肯定应该没有问题的,不会冲突。但是
这样又带来了一个代码维护不方便的问题。如果Function C需要修改,必须将线程A和线程B
中的这个函数都改一边,很麻烦。如果采用类继承,新建一个父类,包含 Function C函
数,线程A和线程B都继承这个父类,但是反汇编结果 call xxxx是指向一个地址,和最初
的公用一个单元的结果类似。各位大虾还有没有更好的方案了,两个线程即可公用一个函数,效率高,又不会冲突?

2.线程事件和回调函数方面:
多个线程同时发出同一个事件,接受事件会不会漏掉过于频繁的事件?
另外,多个线程调用同一回调函数,会不会产生第一个问题的冲突?

3.COM接口方面:
大家都知道,windows的dll动态库输出的字符串是有长度限制的,除非使用pchar类型或
是使用sharemem单元。而com接口传出的字符串(比如bstr*,VARIANT *)好像没有长度限
制,我试验过了。
我的理解:bstr*,VARIANT * 本身传出来的是地址,所以长度是没有限制的。但是这个
地址是谁在管理,并最终销毁?不知道com接口传出字符串长度有没有限制?能否给个明确的回答?
 
没人知道么
 
1.不会有问题.函数的参数是靠栈/或寄存器传递的.函数的局部变量在栈中.每个线程都有自己的栈空间.函数的在那个线程中执行就使用哪个线程的栈空间.所以不会有冲突.寄存器是由CPU的操作系统维护调度的,也不会有问题.
2.同1,也不会有问题.
3.由调用方负责维护而不是被调用方
 
谢谢wr960204大虾的回答,对windows的一些机制有了更深刻的了解。
我原来的理解是错误的,不应该出现我想的那样的结果。
线程会建立自己变量的副本,也会建立自己独立的事件和消息队列(我又在delphi5从入门
到精通的书上证实)。所以不用担心混乱的事情,除非使用全局变量。不知道我理解的对不对?

另外,第三个问题.“由调用方负责维护而不是被调用方”,那不是和dll动态库一样了么,谁调用,谁负责申请内存地址,最后自己负责销毁。
com是不是和这个相反?不是由调用者销毁,而是提供者自动销毁?
 
Com好像也是有调用者负责的吧。
 
调用者只需要使用com接口的函数,好像没有进行任何销毁工作?不太清楚,请高手指点
 
每一个线程都运行在自己的空间,即使“Call xxxx,call指向的地址是一样的”,但他们的基址不同。
 
不会漏掉

bstr等以特定字符结尾#0。
 
bstr* 应该是地址
 
后退
顶部