怪事~~~

奔雷手 2008-10-15 09:20:37
我用多线程读取TXT文本.这之间的读的过程能够用工具查看. 在单独给某个或者某几个线程设置断点的时候 能够很清楚的看到他们都在执行,而不设置断点的时候这么多线程 它只会执行其中一个(完整的一个,不完全的两个,还有多个没反映的).这是什么原因. 难道说断点可以查看到本来不去执行的代码的情况?????? 有没有人碰到这样的情况,或者给我一个明白的解释.
...全文
122 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
奔雷手 2008-10-21
  • 打赏
  • 举报
回复
问题终于解决.都不是上面的问题.不过很谢谢大家.揭贴
lake_cx 2008-10-17
  • 打赏
  • 举报
回复
API函数肯定是线程安全的,所谓线程安全就是看其中有没有用临时变量,是否是互斥访问的。
例如:
假设LoadFromFile中用了个FFileName来存文件名
代码是这么写的:
1:FFileName := FileName;
2:AStream := TFileStream.Create(FFileName, fmOpenRead);
3:LoadFromStream(Stream);
假设两个线程同时调用LoadFromFile,线程1执行了第一句,FFileName成了C:\2.txt,然后线程切换了,线程2也执行了第一句,把FFileName改成了C:\3.txt,然后线程再切换,线程1又开始执行,此时LoadFromFile方法就连文件都弄错了。。。
所谓线程安全就是方法里面考虑了多线程情况,会针对它进行处理保证其不会出错。
奔雷手 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lake_cx 的回复:]
你如果加上临界区,就跟单线程没什么区别了,因为一个线程在LoadFromFile的时候其他线程全部阻塞了,也就不存在同时有ReadFile的调用了。当然,正常情况想应该每个线程都能正常运行的完毕的,不过我不太清楚LoadFromFile方法是不是线程安全的。
[/Quote] 那如果想去读取文本里的内容 什么函数可以说是安全的呢
奔雷手 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 XavierDelphi 的回复:]
线程Execute的部分贴一下就知道了
[/Quote]

begin
getmem(DataBuff,256);
DataLen:=255;
sendpci.dwProtocol:=SCARD_PROTOCOL_T0;
sendpci.dbpcilength:=sizeof(sendpci);

sl :=TStringList.Create;//存储载入的文本文件
sl.LoadFromFile('c:\cos1.txt');
for l:=0 to sl.Count-1 do //逐行处理
begin
sendbuff:=Hex2Bin(sl.Strings[l]);
Lensend:=Length(SendBuff);
ret:=SCardTransmit(hCard,SendPci,sendbuff,Lensend,SendPci,DataBuff,DataLen);
if ret<>0 then
begin
edit14.Text:='ERROR';
Exit;
end;
end ;
sl.Free;
end

这是最关键的一步, 屏蔽了这部分就没有问题.

还有别的可能的话就是 我在主程序里把 mythread0:=Transmit0.create;
mythread0.Resume;放一起了,这样有问题吗
僵哥 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lch0422 的回复:]
引用 2 楼 mygodsos 的回复:
是不是你的txt打开是独占方式

这个打开方式 我不知道哪儿设置.我用的是loadfromfile('abc.txt'),这个没有方法设置打开文件的模式的.
暂且不说这样的,极端的做法是复制N份同样的文件,1线程对应abc1.txt,2 线程对应abc2.txt. 这样的话,我也不需要临界区. 每个线程对应单独操作.
我只知道我这样做的结果没有达到预期的目的,也就只能执行一小部分的线程.
这样的话,会产生什么样的问题呢???
[/Quote]
LoadFromFile是一次性加载,即使所有线程使用同一个文件,也不会有文件锁的问题.
奔雷手 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mygodsos 的回复:]
是不是你的txt打开是独占方式
[/Quote]
这个打开方式 我不知道哪儿设置.我用的是loadfromfile('abc.txt'),这个没有方法设置打开文件的模式的.
暂且不说这样的,极端的做法是复制N份同样的文件,1线程对应abc1.txt,2 线程对应abc2.txt. 这样的话,我也不需要临界区. 每个线程对应单独操作.
我只知道我这样做的结果没有达到预期的目的,也就只能执行一小部分的线程.
这样的话,会产生什么样的问题呢???
我TMD就是天才 2008-10-16
  • 打赏
  • 举报
回复
线程Execute的部分贴一下就知道了
DumDum 2008-10-16
  • 打赏
  • 举报
回复
你设置了临界区之后肯定是其中一个在读取时,其他的线程就被挂起了啊~~!
僵哥 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mygodsos 的回复:]
是不是你的txt打开是独占方式
[/Quote]
独占方式下,其它工具软件是无法查看内容的.

比较大的可能是,线程之间是不是使用了Synchronize串行执行,或者做了互斥操作.
奔雷手 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lake_cx 的回复:]
那就要看读文件的API函数对于多线程是怎么处理的了,一般对于多任务它会优化的。
例如你同时拷贝两个文件肯定不如先拷贝其中一个后拷贝另外一个来得快,针对磁盘这种低速设备,交叉读写显然不可取,所以微软会将这种IO操作进行多线程的优化。
而当你下断点了之后,IDE会将进程的所有线程挂起,IO完全空闲了,所以另外的线程自然可以拥有其控制权。

以上为个人理解,仅供参考。
[/Quote]
恩,完全有这种可能.我用的是TTHREAD.我也仅仅是读,不需要写.希望能指点指点,这样的问题怎么解决.而且我也设置了临界区.加了临界区之后的状况一样.
lake_cx 2008-10-16
  • 打赏
  • 举报
回复
mythread0:=Transmit0.create;
mythread0.Resume;//如果你创建时没把线程挂起,这一句就没什么用,不过有它也不会带来错误
lake_cx 2008-10-16
  • 打赏
  • 举报
回复
你如果加上临界区,就跟单线程没什么区别了,因为一个线程在LoadFromFile的时候其他线程全部阻塞了,也就不存在同时有ReadFile的调用了。当然,正常情况想应该每个线程都能正常运行的完毕的,不过我不太清楚LoadFromFile方法是不是线程安全的。
mygodsos 2008-10-15
  • 打赏
  • 举报
回复
是不是你的txt打开是独占方式
lake_cx 2008-10-15
  • 打赏
  • 举报
回复
那就要看读文件的API函数对于多线程是怎么处理的了,一般对于多任务它会优化的。
例如你同时拷贝两个文件肯定不如先拷贝其中一个后拷贝另外一个来得快,针对磁盘这种低速设备,交叉读写显然不可取,所以微软会将这种IO操作进行多线程的优化。
而当你下断点了之后,IDE会将进程的所有线程挂起,IO完全空闲了,所以另外的线程自然可以拥有其控制权。

以上为个人理解,仅供参考。

830

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧