事件对象手动重置,错误的线程同步

时间:2014-05-25 14:45:59

标签: c windows multithreading events synchronization

我正在接近C Windows编程,特别是线程,并发和同步。

为了实验,我正在编写一个接受N个参数的C程序 每个参数都指示文件系统目录树的路径,程序必须比较所有目录的内容,以确定所有目录是否具有相同的内容。
主要是"阅读"每个参数的线程,而单个"比较" thread比较找到的所有条目的名称。对于找到的每个文件/目录,"阅读"线程通过激活"比较"来同步自己。线程。

我用Semaphore个对象编写了程序,现在我尝试使用Event个对象。
我们的想法是使用N Events auto-resetsingle Event manual-reset

N"阅读&#34>使用N个事件。线程表示"比较" WaitForMultipleObjects时间INFINITE的线程。当所有信号都可用时,它开始比较条目,然后为手动重置对象执行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);

     }

}

问题:

有时候,一个阅读线程能够在不尊重与其他线程同步的情况下工作。如果我在比较线程的等待和设置之间放置printf()Sleep(1),则程序运行良好。

我的意见:

我认为手动重置事件对于这种(屏障)同步是不安全的 读取线程在ResetEvent()中可能太快,如果调度程序减慢了其他线程的速度,则其中一些线程可能会被阻塞,而执行重置的线程可能会继续其工作。
但是,如果是这种情况,比较线程应该在WaitingForMultipleObjects上阻塞自身导致死锁...实际上没有死锁但是1个线程能够相对于其他线程循环更多次。
/> 我想要了解的是为什么简单的睡眠(1)可以解决问题。是调度还是错误实现同步?

谢谢。

0 个答案:

没有答案