多线程程序中数据同步的问题
我知道如果有很多数据的话,需要进行同步,否则有可能第一个数据已经进行了更新,第二个数据还没有进行更新
如果一个类,里面有一些成员变量,好像要进行同步
我看介绍线程的书上,像int float这种基本类型,好像都没有采取同步措施
到底什么时候才需要同步呢。现在我为了保险,只好如果有两个线程使用相同的数据,就进行同步保护
像CString等类型需不需要同步呢
问题点数:20、回复次数:8Top
1 楼huanyun(无妻徒刑)回复于 2003-11-01 12:16:14 得分 0
使用临界区
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection // address of critical
// section object
);
VOID EnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection // pointer to critical
// section object
);
VOID LeaveCriticalSection(
LPCRITICAL_SECTION lpCriticalSection // address of critical
// section object
);
Top
2 楼vcforever(累)回复于 2003-11-01 12:33:55 得分 0
只要是共享资源就需要同步;
可选择的同步对象很多,你可以使用MFC的同步对象CCriticalSection,CMutex,CEvent.....
也可以使用Win32的同步对象CRITICAL_SECTION,Event,Mutex.....
具体使用方法参见MSDN!Top
3 楼byyyyy(苦行僧【苦】)回复于 2003-11-01 22:01:38 得分 0
楼主你好,如果你用的同步函数太多的话就失去了多线程的优点了.
建议把定义的类的派生类重写容易冲突的函数,这样就可以使你的类是线程安全的了.
cstring需要同步,很容易造成冲突.Top
4 楼lwang337(初一)回复于 2003-11-02 16:09:24 得分 0
我的数据都放在共享内存中,好几个进程共用,用Mutex太好资源了。我看有人是这样做的,定义了一个结构,例如
struct SharedData
{
int i;
double j;
char[20] c;
bool IsValid;
}
然后他在访问共享内存的时候先判断IsValid变量,用它来起到一个锁的作用。我觉得这样还是会有同步的问题啊
byyyyy(),我有一个线程进行数据采集,一个计算,一个显示,一个实时打印,一个进行网络数据传输,所以需要很多同步。
大家遇到这种情况都是怎么办的。
还有,关键是需要进程间同步,必须用mutex,他的开销太大了Top
5 楼lop5712(LOP)回复于 2003-11-02 21:23:05 得分 0
并不是共享数据就一定得同步(最简单的某一时刻只读的数据就不用同步),有个方法可以很简单的判断是否需要同步——是否出现别名现象及是否需要事务。
即共享数据被访问时是否会出现先将数据放到一个缓冲(一般是寄存器)或用一个指针来引用数据,都可认为出现了别名现象。此时需要同步。
当共享数据很长时(对其存取需要2个指令以上)需要保证数据完整性,也就要求事务功能。此时需要同步。
因此楼主上面说的那个IsValid变量的存取,由于bool只是4个字节长,可以简单的用Win32 API提供的原子函数赋值即可(抱歉,函数名记不到了,手边没有资料,不能帮楼主查)。因此楼主说的某人的方法是可以的,不过最好还是将IsValid换成一个Event(如果楼主嫌互斥量太浪费)。
如果楼主觉得要多次调用同步用函数,太亏了,那么就只有从算法上做改进。举例:
将楼主的共享数据封装成一个结构(正如上面楼主的那个结构),不过共享内存中放的不是结构的一个实例,而是一个数组。由于楼主有5个线程操作这个共享内存,因此数组的维数可以使用5,每个线程再每次对数据操作一次后,依次将自己的数据指针指向上一个数组元素,如:
“数据采集”线程操作元素0,此时“计算”操作元素1(先已被“数据采集”操作过),而“显示”、“实时打印”和“网络数据传输”一起操作元素2(先已被“数据采集”操作,再被“计算”操作过),之所以可以一起操作元素2,因为那三个都是只读的。
每个线程操作完后,都再移到上一个元素(当然,元素0移到元素2),当然,对每个元素的操作仍需要同步,因此从代码上看,对同步函数的调用没有减少,不过在运行时,由于等待同步元素而致使线程的模式切换(从内核模式切换到用户模式及反向切换;线程间切换的损耗)的时间将大大减少(可以通过观察哪些线程运行长,将这些线程操作的元素相隔远点(即“数据采集”操作元素0时,“计算”操作元素3),以减少线程的等待。Top
6 楼lwang337(初一)回复于 2003-11-02 23:03:32 得分 0
对于 lop5712(LOP) 说的,我还是不能赞同,即使可以用IsValid判断是否可以操作,但也可能在你取出IsValid的值的时候还是好的,但还没等你改变它的值并对数据进行操作的时候,其他线程就得到了执行权,结果还是两个线程同时操纵数据
大家有没有比较复杂、处理得比较好得多线程程序让我观摩一下,看看怎么同步。最好是4个线程以上。
我的信箱: chuyi@ustc.eduTop
7 楼lop5712(LOP)回复于 2003-11-03 12:22:17 得分 20
呵,抱歉,楼主说的是对的,没注意到。不过这并不影响我后面说的算法,并且我也说过用Event替换它就没事了。我的那个算法说的形象点就是流水线处理,如果楼主觉地不够复杂,我也只有这点实力。Top
8 楼lop5712(LOP)回复于 2003-11-03 12:34:31 得分 0
不好意思,上面说错了,应该是Mutex,而不是EventTop




