关于STL底层空间配置器std::alloc的疑问。

疯魔症 2011-09-02 12:41:49
看《STL源码剖析》,其中空间配置器没有对多线程情况下做说明。
但是在std::alloc的类中有如下的成员:
static obj * void volative free_list[_NFREELISTS];

我觉得这中声明在多线程情况下肯定有问题啊。
我的理解:static修饰的变量,在整个应用程序的内存空间中只有一份,那么多个线程使用STL时,STL做内存分配使用的是同一个内存,肯定要出错的。
是不是STL的内存分配函数使用了线程同步或其他处理。
...全文
220 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
lifesider 2011-09-02
  • 打赏
  • 举报
回复
针对多线程的情况,STL有明确说明以下两点:
(1)多个线程的读是线程安全的;
(2)多个线程的写不是线程安全的;
其实这两点很好理解,容器的操作由于是封装类实现,因此是没必要作线程安全的
对于内存管理上,std::allocator类默认使用的是::operator new和::operator delete,底层的内存分配是加了锁的(使用关键代码段),具体你跟进行就明白了
iaccepted 2011-09-02
  • 打赏
  • 举报
回复
stl的内存分配可以支持多线程。但是stl并不支持多线程啊,在多线程情况下是会出错的。
欢迎交流学习。
luciferisnotsatan 2011-09-02
  • 打赏
  • 举报
回复
stl没说是线程安全的
jackyjkchen 2011-09-02
  • 打赏
  • 举报
回复
肯定没有线程同步,因为STL不会加锁的

你这个没有上下文,我也搞不太清楚,一般线程安全的STL都是指内存分配的线程安全,这样不同的容器对象就可以并行操作,《STL源码剖析》针对SGI STL,是线程安全STL的鼻祖
taodm 2011-09-02
  • 打赏
  • 举报
回复
stl源码剖析是展示sgi stl代码核心的,并发编程代码被刻意省略了
真好奇这事,请自己认真直接看sgi stl源码。
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
这段是 《STL源码剖析》第二章空间配置器的一部分代码。这里使用了内存池,我觉得多线程的话这里肯定有问题的。上面有人说,windows下STL版本没有使用内存池,所有没问题。如果是这样,我下周就结贴了。
enum{__ALIGN =8};
enum{__MAX_BYTES=128};

enum{__NFREELIST = __MAX_BYTES/__ALIGN};

template <bool threads,int inst>
class __default_alloc_template //使用了内存池的第二级配置器
{
private:
......
private:
//16个free-lists
static obj * volatile free_list[__NFREELIST]; //
private:
......
public:
static void * allocate(size_t n);
static void * deallocate(void * p,size_t n);
static void * reallocate(void * p,size_t old_sz,size_t new_sz);
}

//vector中使用

template <class T,class Alloc=alloc> //这里默认使用的alloc分配内存
class vector
{
......
}
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
就是这样,里面是使用了内存池的,为了防止频繁分配小额内存造成内存碎片过多,所以大于128字节时直接用malloc和delete,小于128字节时使用内存池。
如果windows上的或VS的STL版本没使用内存池的话,内存碎片会不会太多了啊。
[Quote=引用 15 楼 fengxuxing 的回复:]

引用 14 楼 zwb0540822 的回复:

我要问的不是多线程对公共变量的读写,这种情况我会用临界区加锁解锁。
起因是我在看《STL源码剖析》时,其中第二章空间配置器,给的源码在多线程情况下应该会
出问题的,所以有点困惑。
引用 13 楼 fengxuxing 的回复:

stl只保证多个一起读是安全的,其它的都不安全

STL源码剖析里面采用的是sgi的源码,里面使用内……
[/Quote]
Qlaiaqu 2011-09-02
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zwb0540822 的回复:]

我要问的不是多线程对公共变量的读写,这种情况我会用临界区加锁解锁。
起因是我在看《STL源码剖析》时,其中第二章空间配置器,给的源码在多线程情况下应该会
出问题的,所以有点困惑。
引用 13 楼 fengxuxing 的回复:

stl只保证多个一起读是安全的,其它的都不安全
[/Quote]
STL源码剖析里面采用的是sgi的源码,里面使用内存池,你看源码就知道,里面的操作是没有加锁的,多个线程同时写操作,导致内存分配,按照内存池的设计,就有可能一个内存被先后从内存池中拿出来赋值给不同的变量,这时候是绝对的不安全的。windows里面的pj版本的stl可能安全一点,里面没有内存池的概念,所有的操作都是new,这个在某种意义上将,出错的可能性小很多。
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
我要问的不是多线程对公共变量的读写,这种情况我会用临界区加锁解锁。
起因是我在看《STL源码剖析》时,其中第二章空间配置器,给的源码在多线程情况下应该会
出问题的,所以有点困惑。
[Quote=引用 13 楼 fengxuxing 的回复:]

stl只保证多个一起读是安全的,其它的都不安全
[/Quote]
Qlaiaqu 2011-09-02
  • 打赏
  • 举报
回复
stl只保证多个一起读是安全的,其它的都不安全
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
我理解的这句是不是有问题啊。[Quote=引用 10 楼 q191201771 的回复:]

static修饰的变量,在整个应用程序的内存空间中只有一份

这句话说得很有歧义, 应该说类的静态数据成员吧
[/Quote]
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
是这个意识:类的静态数据成员。
[Quote=引用 10 楼 q191201771 的回复:]

static修饰的变量,在整个应用程序的内存空间中只有一份

这句话说得很有歧义, 应该说类的静态数据成员吧
[/Quote]
就想叫yoko 2011-09-02
  • 打赏
  • 举报
回复
static修饰的变量,在整个应用程序的内存空间中只有一份

这句话说得很有歧义, 应该说类的静态数据成员吧
pengzhixi 2011-09-02
  • 打赏
  • 举报
回复
我记得书中有一个地方说了,SGI有线程安全的版本。只是没讨论
lifesider 2011-09-02
  • 打赏
  • 举报
回复
注意你这里的alloc有是否使用线程作为模板参数template <bool threads,int inst>

template <class T,class Alloc=alloc> //这里默认使用的alloc分配内存
class vector
{
......
}
所以你应该看默认参数alloc的那个threads标志是否传的true
liutengfeigo 2011-09-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 luciferisnotsatan 的回复:]

stl没说是线程安全的
[/Quote]
++
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
回复上没格式输入按钮,抱歉。
疯魔症 2011-09-02
  • 打赏
  • 举报
回复
enum{__ALIGN =8};
enum{__MAX_BYTES=128};

enum{__NFREELIST = __MAX_BYTES/__ALIGN};

template <bool threads,int inst>
class __default_alloc_template //使用了内存池的第二级配置器
{
private:
......
private:
//16个free-lists
static obj * volatile free_list[__NFREELIST]; //
private:
......
public:
static void * allocate(size_t n);
static void * deallocate(void * p,size_t n);
static void * reallocate(void * p,size_t old_sz,size_t new_sz);
}

//vector中使用

template <class T,class Alloc=alloc> //这里默认使用的alloc分配内存
class vector
{
......
}

那么多个线程中使用vector时,他们内部使用的是同一个free_list。是这样吧。

64,640

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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