线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通信)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。windows
涉及多线程程序涉及的时候常常会出现一些使人难以思议的事情,用堆和栈分配一个变量可能在之后的执行中产生意想不到的结果,而这个结果的表现就是内存的非法被访问,致使内存的内容被更改。
理解这个现象的两个基本概念是:在一个进程的线程共享堆区,而进程中的线程各自维持本身堆栈。
另外一运行机制就是若是声明一个成员变量如 char Name[200],随着这段代码调用的结束,Name在栈区的地址被释放,而若是是 char * Name = new char[200]; 状况则彻底不一样,除非显示调用delete不然 Name指向的地址不会被释放。
在B中若是用栈区 即采用临时变量的机制分配声明V和堆区,而者的结果是不一样的。若是用栈区,若是变量地址为Am1-Am2这么大,退出B调用时候这段地址被释放,C函数可能将这段内存改写;这样当D执行的时候,从内存Am1-Am2中读取的内容就是被改过的了。
而若是用New(堆)分配,则不会出现那样的状况,由于没有显示对用delete而且堆对于线程共享,即2线程能够看到1线程在堆里分配的东西,因此不会发生误写。
这个问题是笔者在公司实习的时候发现的,由于当时刚刚涉及多线程程序设计,操做系统中如此简单的话题困扰笔者好久,但愿能够对初涉C++多线程的读者有所帮助! 2)若是两个线程共享堆,并且都有可能执行内存分配和释放操做,就必须进行同步保护,这个和C类,R类,T类没有关系。你看到的例子两个线程应该是使用各自的堆。
在 windows 等平台上,不一样线程缺省使用同一个堆,因此用 C 的 malloc (或者 windows 的 GlobalAlloc)分配内存的时候是使用了同步保护的。若是没有同步保护,在两个线程同时执行内存操做的时候会产生竞争条件,可能致使堆内内存管理混乱。好比两个线程分配了统一块内存地址,空闲链表指针错误等。
Symbian 的线程通常使用独立的堆空间。这样每一个线程能够直接在本身的堆里分配和释放,能够减小同步所引入的开销。当线程退出的时候,系统直接回收线程的堆空间,线程内没有释放的内存空间也不会形成进程内的内存泄漏。
可是两个线程使用共用堆的时候,就必须用 critical section 或者 mutex 进行同步保护。不然程序崩溃时迟早的事。若是你的线程须要在共用堆上无规则的分配和释听任何数量和类型的对象,能够定制一个本身的 allcator,在 allocator 内部使用同步保护。线程直接使用这个 allocator 分配内存就能够了。这至关于实现本身的 malloc,free。可是更建议你从新审查一下本身的系统,由于这种状况大多数是没必要要的。通过良好的设计,线程的本地堆应该可以知足大多数对象的需求。若是有某一类对象须要在共享堆上建立和共享,这种需求是比较合理的,能够在这个类的 new 和 delete 上实现共享保护。多线程
转自:http://laiyuanyuan7.blog.163.com/blog/static/15274321201241191321666并发