当前位置:主页>销售管理软件> 列表

同进程内各线程间用消息传递数据,用什么方式好些。动态数组指 找进销存系统需求

销售管理软件版1楼: 我用发送自定义消息的方式,wparam中是待发送数据的指针。
因为待发送数据是随时频繁从socket读取出来的,所以是随时分配内存,然后由处理线程释放内存,
可是我把待发送数据内存区声明为 array of char, 然后用setlength分配内存,传递后,内容却读不出来,
用record指针吧,每次都要new,dispose,
用自定义的数据对象吧,每次都要create,free,
有什么好的方法来传递,同时又少占系统资源,尽量避免频繁的内存分配释放。
另外,我用setlength分配的动态数组,传数组指针后,怎么就读不出来了呢,是我写错了吗? 还是不能这样用,因为这段代码我已经删掉了,所以没法提供,目前使用的是create,free。呵呵。

2楼: 就用固定的缓冲区好了,不要动态分配比较好,比如:
var
Buf: array [0.255] of Char; 如客户管理软件下载

3楼: 固定的缓冲区,长度是从socket读出的,有的包很长,远不止255,这样做是不是太浪费内存了? 还有,我是在另一个线程中对这个缓冲区处理的,接收线程只是负责生成一块内存区域,把接收到的包放入,然后通知另一个线程来做处理后就不管了。所以局部变量的缓冲区在处理过程里还会存在吗? 如果用全局的固定缓冲,那么下一个包发来时,岂不是要覆盖这个缓冲?

4楼: To shangshang,


你的QQ或MSN多少?
我看看你的代码

5楼: -->可是我把待发送数据内存区声明为 array of char, 然后用setlength分配内存,传递后,内容却读不出来,
这个是因为你传递的方式不对,必然a:array of char
那你传递是应为@a[0],而不是@a

6楼: to: delphilxh, 我传递的就是@a[0]的,传递前好好的,消息处理过程里却出来一堆乱码。

to:老人家, 我的代码牵扯太多,况且现在只有create ,free模式的传递代码,很稳定,我就是嫌弃每次都要create对象在内存中,担心开销大,内存会有碎片什么的影响,所以才希望有更简便的方法。
我的qq:346970558 ;msn:ypv9@hotmail.com

销售管理软件版7楼: -->可是我把待发送数据内存区声明为 array of char, 然后用setlength分配内存,传递后,内容却读不出来,

你是用PostMessage来发消息的吧? PostMessage不会保存wparam,lparam里的内容,改用 SendMessage, 然后用setlength分配内存应该可以读出来的.

8楼: PostMessage不会保存wparam,lparam里的内容 ??

不可能吧? 那要这俩参数干嘛啊? 我想你错了.
我用的postthreadmessage. 传到处理线程的消息队列中,等待处理,
posthreadmessage会立刻返回.

9楼: MSDN上找来的


If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail. The functions will return before the receiving thread has had a chance to process the message and the sender will free the memory before it is used.

如果是posthreadmessage不知道会不会.

10楼: 我的是自定义消息,我已经看到传递后的正确结果了,是可以访问这个setlength后的缓冲区的,只是担心他会否已经被系统标记为未使用.因为这段内存是在另一个线程的局部动态数组中申请的.

我现在的create ,free方法如何? 想请各位评论一下下.

11楼: 不要频繁分配释放内存,否则严重影响效率!
可以采用内存池。

12楼: 感谢Kingron大侠您可是经常指点我的问题的噢.呵呵
我也是担心频繁的创建释放会引发类似内存碎片过多的问题吧,我现在又改成了allocmem一个pchar,处理后freemem. 或许比创建对象好些.
至于您说的内存池,我不太明白怎么实现,对象池的概念好明白.
至于内存,我所需的内存是不确定的,难道用时事先申请个几M内存?然后用时再初始化一段区域,然后把区域指针和长度拿来使用?
在我的处理机制中,这个需要传递的结构总数量在不同时刻差别很大,通常只有一个,发送时却设计为可以达到几万个甚至更多来等待处理.内存池合适吗?
另,能否讲一下频繁创建释放对象,申请和释放内存到底能带来什么样的副作用吗? 如进销存免费版

13楼: 一次分配几M内存也没有什么啊!不用担心内存问题。和效率相比,内存不重要。
频繁分配内存会有碎片问题。而且多线程程序经常分配内存,会在分配内存的时候加锁,影响效率。

销售管理软件版14楼: 收藏!

15楼: 严重同意Kingron,现在都什么时代了,2M内存值几分钱啊,既然写多线程,看中的当然是效率。

16楼: 一次分配几M内存也没有什么啊!不用担心内存问题。和效率相比,内存不重要
---------------------------------------------------------------------
是的,我并不担心几M内存,我通常也是倾向于使用pooling的,只是至于一个缓冲区
的分配,如果也用事先分配一大段连续的内存的话,我自己不得管理每块小区域的使用
状态嘛,每个record的大小还不同,要重用一小区域的话,难道还要计算这个空闲区域的指针到后面的第一个有用区域的指针之间的大小是否足够? 这样太烦琐吧.

17楼: 没有最好,只有最合适。

我不想讨论低水平的缓冲池、预分配内存、几兆、几十兆,我看还是应该从程序的主体结构来看待数据与程序的关系。用很多方法都可以得到想要得到的目的,而且从本质上看,没有一个数据块不是动态创建和管理的。

这就看你看问题的角度了。你把某些能够在 GUI 显示的东西称为数据,把为这个显示服务的数据称为变量,那么你就陷入了怎么办才最好的框框。

一个数据如何使用,决定了数据本身应该以怎么样的一种形式存在(注:仅是个人认为)。而存在的形式决定了管理、检索、处理的方式。如果仅仅看一个数据块,是没有哪个高人能够提出一语走天下的妙策的。所以我认为不要单独拘泥于数据块,建议从程序本身的结构来看待这个问题。

我有很多的例子可以罗列出来,不过我常常不是很有兴趣罗列。

18楼: 另外,记录和内存块是一回事。希望楼主明察!

19楼: flamingo,你说的有些形而上学了,我没法否认你的观点,但不可否认,你的观点对我的问题并不适合,如果说我的数据处理的程序架构设计有问题,那上面我已经说了我的处理思路,请指出更好的方法吧. 不胜感谢.我提问题本就是希望有经验的高手指出我的不足,给我几种更好的设计处理的方法.

记录和内存块是一回事.
-----


是的,我也这样认为,我并没有在我的回答里把他们区别看待.

20楼: 线程有线程管理器,内存有内存管理器,假如没有就自己建一个!这不是在玩过家家,这是在写程序!

确实,我可以提供n多的代码来完成你需要的处理,包括你说的“要重用一小区域的话,难道还要计算...”,我也可以提供n个方案供你参考。但你目前还不需要这些,道不同不与为谋,你还是继续在低水平的代码处理上多转转吧。

销售管理软件版21楼: 用一个内存块链表来管理你遇到的问题,在驱动开发里,可以用looksidelist,也称为后备链表。原理是预先估计你的程序将使用的最大内存量,申请一个这么大的内存块,然后把大内存块等分为n个小块,用链表进行管理,需要内存的时候就直接查询链表中空闲的数据块,找到后把空闲位置为非空闲状态,内存用完后再把非空闲状态置为空闲状态,这样不用频繁的申请和释放内存。在linux内进程间通讯,我都用共享内存加信号量实现这种方案。你的线程在同一个进程内,直接用临界区+我所说的内存池就可以了。

22楼: flamingo有点偏激,不过也有道理的。
多线程的程序如果处理数据量有限,没有什么关系,怎么做都可以了。
另外还有一个问题:多线程的程序在多CPU上跑就会有严重的内存操作性能问题的。有兴趣你可以去找一台多CPU的服务器去测试看看。
使用内存池,可以根据你的纪录的大小,并添加一个Flag,表明该数据是否被用还是没有被用,也可以采用两个指针计数来做。
我现在的做法是多进程来提高性能。 :D 如进销存系统需求

23楼: 谢谢 爱元元的哥哥,Kingron, 同时也很感谢 flamingo 的批评评价.
我的确是刚开始写socket通讯才两个月,确实是低水平,:)
以前一直做MIS的,偶尔做些工具.没仔细考虑过这方面的问题,
在做这个程序的时候,因为没什么可参考的,只是自己翻了些资料和讨论,
自己构思设计出的这些处理方法,就因为自己没把握,所以才希望各位指出问题,
能教我一些成熟的处理方法,我更感激不尽.
我是抱着学习和接受批评的想法提出这个帖子的.请各位有什么想法,尽管敞开了说.
to:爱元元的哥哥,我现在用的TThreadList来管理已分配的内存,不过没有预分配空间,因为我的每个包都是不定长的,长度最大值虽然可以估算,我怕不可靠,所以...呵呵.
另外往threadlist增加是不限制的,也就是允许一直增加,不考虑内存承受不了的极限.
这样做是不是不太好呢?
我还想明白一下内存碎片的原理和后果.
to:kingron 你说的内存池的使用方式应该是和爱元元的哥哥的方法类似的,也最好确定每块的大小吧.

24楼: 最好的解决方案是动态增长的内存池

虽然封包的长度不能确定,但在所有通信的封包中肯定有一个封包的长度是最大的,使用动态增长的内存池能正好使被分配的内存达到封包所需要的最大临界值。这样即不会浪费空间也不会频繁得创建与释放内存,因为内存只有在空间不够的时候才重新被分配一次,如果空间足够那么将一直使用原来的那块内存空间。

25楼: 不说了,其实你也挺不错的,我也已经说话很客气了。

在最初 kingron 提出的东西后我就知道你没法摆过来弄,不是 kingron 的方法有问题,而是他也忽视了整体结构对方法移植的难度,里面其他一些捧场的说这说那就不必管他了,链表也是在我说了后才有人提到。

我也不罗嗦了,反正我也没打算在这里帮任何人,看得懂我说的最好,看不懂当我瞎说吧。

26楼: 我现在也是刚开始试着写,如果大侠不想仔细了解我的思路,尽管提示一些完整处理过程,我的代码推翻了重来都行.呵呵.
相信大富翁仍是我辈求学者的天堂.

27楼: 呵呵,想不到火药味有点儿浓烈啊,flamingo大虾应该是位完美主义者,兄弟敬佩。
我想还是楼上那位说的好,没有最好的,只有最合适的,软件写出来本来就是为了用的,好用、够用,那就够了,艺术家有艺术家的活法,泥瓦匠也有泥瓦匠的饭吃:)

销售管理软件版28楼: 智者见智,任何方法都有一定的结果.呵呵.谢谢诸位指点.结了.