C 事件对象手动重置,线程同步错误
我正在学习C Windows编程,特别是线程、并发和同步。C 事件对象手动重置,线程同步错误,c,windows,multithreading,events,synchronization,C,Windows,Multithreading,Events,Synchronization,我正在学习C Windows编程,特别是线程、并发和同步。 为了进行实验,我正在编写一个接受N个参数的C程序。 每个参数表示文件系统目录树的路径,程序必须比较所有目录的内容,以确定所有目录是否具有相同的内容。 main为每个参数运行一个“读取”线程,而单个“比较”线程则比较找到的所有条目的名称。对于找到的每个文件/目录,“读取”线程通过激活“比较”线程进行同步 我用信号量对象编写了程序,现在我用事件对象进行了尝试。 想法是使用N事件自动重置和单事件手动重置 N个事件被N个“读取”线程用来向Wai
为了进行实验,我正在编写一个接受N个参数的C程序。
每个参数表示文件系统目录树的路径,程序必须比较所有目录的内容,以确定所有目录是否具有相同的内容。
main为每个参数运行一个“读取”线程,而单个“比较”线程则比较找到的所有条目的名称。对于找到的每个文件/目录,“读取”线程通过激活“比较”线程进行同步 我用
信号量
对象编写了程序,现在我用事件
对象进行了尝试。想法是使用
N事件自动重置
和单事件手动重置
N个事件被N个“读取”线程用来向WaitForMultipleObjects
中的无限时间的“比较”线程发送信号。当所有信号可用时,它开始比较条目,然后对手动重置对象执行SetEvent()
。
“读取”线程等待此设置,然后重置事件并继续处理下一个条目
N个读取线程的一些代码:
void ReadingTraverseDirectory(LPTSTR StartPathName, DWORD i) {
//variables and some work
do {
//take the next entry and put it in current_entry;
gtParams[it].entry = current_entry; //global var for comparison
SetEvent(glphReadingEvent[i]); //signal the comparison thread
WaitForSingleObject(ghComparisonEvent, INFINITE); //wait signal to restart working
ResetEvent(ghComparisonEvent); //reset the event
if (current_entry == TYPE_DIR) {
ReadingTraverseDirectory(current_entry, i); //recur to explor the next dir
}
} while (FindNextFile(SearchHandle, &FindData)); //while there are still entries
//
return;
}
比较线程的一些代码:
DWORD WINAPI CompareThread(LPVOID arg) {
while (entries are equal){
WaitForMultipleObjects(N, glphReadingEvent, TRUE, 1000);
for (r = 0; r < nworkers - 1; r++){
if (_tcscmp(entries) != 0){
//entries are different. exit and close.
}
}
SetEvent(ghComparisonEvent);
}
}
DWORD WINAPI CompareThread(LPVOID arg){
while(条目相等){
WaitForMultipleObjects(N,glphReadingEvent,TRUE,1000);
对于(r=0;r
问题:
有时,一个读数线程能够在不考虑同步器与其他线程的情况下工作。如果我在Wait和比较线程Set之间放置一个printf()
或Sleep(1)
,程序工作得很好
我的意见:
我认为手动重置事件对于这种(屏障)同步是不安全的。
ResetEvent()
中的读取线程可能太快,如果计划程序减慢了其他线程的速度,则在执行重置的线程能够继续工作时,其中一些线程可能会处于阻塞状态。
但是,如果是这种情况,比较线程应在WaitingForMultipleObjects
上阻塞自身,从而导致死锁。。。实际上,没有死锁,但是一个线程相对于其他线程能够循环更多的时间。
我想理解的是为什么简单的睡眠可以解决这个问题。是调度问题还是同步的错误实现
谢谢。我忘了提到glphReadingEvent是自动重置的。在windows开发中心,我读到“一个事件对象,其状态保持有信号状态,直到释放一个等待线程,此时系统自动将状态设置为无信号状态。”