您的位置:首页 > 编程语言 > C语言/C++

多线程---内存模型(C++11)

2015-08-28 12:18 423 查看
多线程的内存模型能够为并发连接或修改内存的线程提供一系列的保证。

首先要强调的一点是:任何对内存对象的操作都不会直接显现在该内存对象上,而是经历一系列操作:内存里的对象加载到cach memory,然后加载到处理注册器,在处理器里面修改,然后写回到cache memory,再写回到内存里面。

同一个进程内的不同线程共享进程的内存。不同线程如果正在运行同一个或不同的处理单元(处理器、内核或超线程等),它们共享cache memory。这样导致线程之间很容易出错。

1)memory model保证两个执行线程在更新/连接“分开的”内存位置时,是不受对方干扰的。内存位置可以是计算类型对象、指针、一段内存连续且长度最长的bit-fields。代码如下:

#include<iostream>
#include<thread>

int b=0;
int c=0;
void fb()
{
b=1;
int x=b;
std::cout<<x;
}

void fc()
{
c=1;
int y=c;
std::cout<<y;
}

struct Str{
int a:3;  //a occupy 2 bits
int b:5;  //b occupy the later 5 bits, and the rest of 4Byter(32bits) leave, don't give to other vars
}; //sizeof(Str)=4 (Byte)

Str* CreateStr(int n, int m)
{
Str *str=(Str*)malloc(sizeof(Str));
str->a=n;
str->b=m;
return str;
}

//overload operator << for cout to ouput struct Str
std::ostream& operator<<(std::ostream &os,Str *s)
{
os<<s->a<< s->b<<"\n";
return os;
}

int main()
{
std::thread tb(fb);
std::thread tc(fc);
tb.join();
tc.join();

Str *s=CreateStr(3,4);
std::cout<<"\nOriginal Str is: "<<s;//show 34
std::thread t1([&s]{
s->a=1;
int x=s->a;
std::cout<<x;});

std::thread t2([&s]{
s->b=1;
int y=s->b;
std::cout<<y;});
t1.join();
t2.join();

std::cout<<"\n";
return 0;
}


运行结果:



更直接的写法是如果把t1、t2中的输出语句

std::cout<<x;
std::cout<<y;


都改成

std::cout<<s;


则输出结果如下:



以上可知,t1先运行,t2后运行,两者不受干扰。

(2)只有在没有data race,且x、y均是一个内存位置时,x=y能保证x是y的副本。但是,如果x、y是multi-word的struct或有data race,就不能保证了,而且行为不确定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 内存模型