by
Quote:
资料上说User::Alloc 这个API 不是线程安全的(似乎除了继承RHandleBase的类是线程安全的其他有关内存的分配的API貌似都不是线程安全的) 那么如果我用了多线程技术,并且这些线程共享了堆区(如果不是共享堆区也就没啥问题了 ![]() ![]() ![]() |
在 windows 等平台上,不同线程缺省使用同一个堆,所以用 C 的 malloc (或者 windows 的 GlobalAlloc)分配内存的时候是使用了同步保护的。如果没有同步保护,在两个线程同时执行内存操作的时候会产生竞争条件,可能导致堆内内存管理混乱。比如两个线程分配了统一块内存地址,空闲链表指针错误等。
Symbian 的线程一般使用独立的堆空间。这样每个线程可以直接在自己的堆里分配和释放,可以减少同步所引入的开销。当线程退出的时候,系统直接回收线程的堆空间,线程内没有释放的内存空间也不会造成进程内的内存泄漏。
但是两个线程使用共用堆的时候,就必须用 critical section 或者 mutex 进行同步保护。否则程序崩溃时早晚的事。如果你的线程需要在共用堆上无规则的分配和释放任何数量和类型的对象,可以定制一个自己的 allcator,在 allocator 内部使用同步保护。线程直接使用这个 allocator 分配内存就可以了。这相当于实现自己的 malloc,free。但是更建议你重新审查一下自己的系统,因为这种情况大多数是不必要的。经过良好的设计,线程的本地堆应该能够满足大多数对象的需求。如果有某一类对象需要在共享堆上创建和共享,这种需求是比较合理的,可以在这个类的 new 和 delete 上实现共享保护。
Quote:
还有就是动态数组RArray的问题,资料显示它也不是线程安全的,由于在APEND的过程中可能需要内存的重新分配,也就是说如果用到上面的共享堆区多线程技术的话,那么我在使用RArray的时候也必须加上同步操作吗![]() |
Symbian的RArray没有任何一个级别的同步保护。如果你的数组被一个线程在本地堆上使用,不需要同步。如果只被一个线程在共享堆上使用,只需要保证分配和释放内存的操作是安全的就可以了。如果需要被多个线程共同操作,还需要根据需要提供容器级或者算法级的同步保护。
There is always a solution, which is so appealing, so quick and so wrong.