有全局变量 int a;
有两个线程A,B;
两线程同时运行,其中A不断改变a的值,B不断读取a的值。
其中不使用同步,B得到的a的值当然是未知数,
理论上系统会出错吗?
有两个线程A,B;
两线程同时运行,其中A不断改变a的值,B不断读取a的值。
其中不使用同步,B得到的a的值当然是未知数,
理论上系统会出错吗?
解决方案 »
- vc 如何调用com接口的dll
- 为什么子窗口的OnPaint无效
- VS2005组合框问题
- 如何利用CListCtrl::DrawItem 或者DrawSubItem来设置CListCtrl的某个SubItem的背景色或文字色?
- 请教大家一个MFC中如何获取句柄的问题?
- 请问用什么命令能得到 网络接口名称 ?
- 很简单的问题,为什么我的vc里边没有GetModuleFileNameEx()这个函数
- ◎◎MIDL编译器无法编译PB生成的COM组件◎◎
- 电脑校时的小程序
- 谁有获取CPU温度的源代码!谢谢了!
- yeah,起步!我的第一个Client/Server,发文以示纪念!!散分
- CRichEditCtrl问题
如果是 四个字节的数据,或者更短的数据,我认为是没问题的。因为数据这么短,
数据的传递应该就是原子操作了。不过也很不好讲。我也不确定
============================================================================
DocWizard C++ 程序文档生成工具 http://www.betajin.com/alphasun/index.htm
你在线程B中所读到的线程A中的数据,
至少在顺序上不是线程A所处理得到数据的顺序。
如果采用进程同步机制才能确保数据的一致性。
mov ax,[a]
mov [g],axmov ax,[g]
mov [b],ax
但这样做程序的移植性就太差了
1。如果数据没有超过数据总线宽度,那么对他的读写是原子操作。(姑且这么说,我也不是很肯定)
2。如果超过宽度,比如 double,那么就不是原子操作。
threadA:
evtNowDraw = CreateEvent(NULL, FALSE, FALSE, "evtNowDraw");
void Write()
{
desBuf=*srcBuf;
// 设置画图事件消息
SetEvent(evtNowDraw);
}
BOOL ThreadA::GetEvent()
{
if(WaitForSingleObject(evtNowDraw,YourWaitTimeOut)!=WAIT_TIMEOUT)
{
this->ResetEventNowDraw();
return true;
}
else
{
return false;
}}ThreadB:
void Read()
{
if(ThreadA::GetEvent(evtNowDraw))
{
buf=desBuf;
}
}
对于32位系统,无论是操作系统还是硬件, DWORD都是 32 位to ybeetle(小鬼)
没错,在这种情况下我不想使用 同步对象,也是处于系统资源耗用的问题。另外程序设计也可以简化。
这个能不能说明一个问题?
>>时,就无所谓了!读是一个原语,不会被中断的!我认为不是这样的,因为写不是原语,所以,即便读是原语, read也会得到不完整的数据。
想想一下write半个数据,read打断了他,虽然read不能被别人打断(姑且这样假设),
read得到的数据就是半个数据。
LONG volatile* lpAddend
);
LONG InterlockedIncrement(
LONG volatile* lpAddend
);
这两个函数是原语操作,由操作系统实现,如果写一个DWORD是原语,那也没有必要
由这两个函数吧?
不过如果该变量的地址没有对齐,我想有可能出错,因为程序要读取内存两次才能取出该变量的值。
例如:
#pragma pack(push, 1)
struct test
{
char ch;
int a;
};test::a的地址没对齐可能出错。
struct test
{
char ch;
int a;
};
test::a的地址应该是对齐的
test::a的地址不是对齐的
if ( a ) // 此时 a != 0.
strcpy(str_buf, (char*)a); // 此时a 被A线程改成了 0 or unvalid address.
同时, 如果机器指令长度超过一个字节, 内存寻址又允许间接寻址的话, 一条指令在执行期间最多可能产生6 次中断!
接下来,我们来讨论一下操作系统如何实现原子操作的吧。