2012-04-13 46 views
0

我在线发现的代码显示了如何使用redKyle教程中的线程。在'Race Condition'教程中,他基本上展示了两个线程如何发送到一个函数。该功能的目标是打印'。'。和'#',每个序列一百次。他提供的代码让这个工作,他不提供互斥体的代码。我修改了代码以包含互斥体,以防止一个线程访问保存在另一个线程访问它时打印的最后一个字符的变量。 我得到的代码工作。大!不过,我一直在改变1到50之间的睡眠值。互斥代码工作正常。但是,当我将睡眠设置为0(或只是将其注释掉)时,互斥锁不再有效,并且值不再以正确的方式打印(我不再看到200个字符严格交替'#'和'。')。为什么睡眠功能禁用我的互斥锁

以下是代码:

#include "stdafx.h" 

#include <iostream> 
#include <windows.h> 
using namespace std; 

static char lastChar='#'; 

//define a mutex 
HANDLE mutexHandle = NULL; 

//flag to specify if thread has begun 
bool threadStarted = false; 

void threadProc(int *sleepVal, int *threadID) 
{ 

    cout<<"sleepVal: "<<*sleepVal<<endl; 

    for (int i=0; i<100; i++) 
    { 

     char currentChar; 

     threadStarted = true; 

     while(!threadStarted){} 

     //lock mutex 
     WaitForSingleObject(mutexHandle, INFINITE); 

     if (lastChar == '#') 
      currentChar = '.'; 
     else 
      currentChar = '#'; 

     Sleep(*sleepVal); 

     lastChar = currentChar; 

     ReleaseMutex(mutexHandle); 

     threadStarted = false; 


     //  cout<<"\nSleepVal: "<<*sleepVal<<" at: "<<currentChar; 
     cout<<currentChar; 
    }//end for 
}//end threadProc 

int main() 
{ 
    cout<<"Race conditions by redKlyde \n"; 

    int sleepVal1 = 50; 
    int sleepVal2 = 30; 

    //create mutex 
    mutexHandle = CreateMutex(NULL, false, NULL); 

    //create thread1 
    HANDLE threadHandle; 
    threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal1, 0, NULL); 

    //create thread2 
    HANDLE threadHandle2; 
    threadHandle2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal2, 0, NULL); 

    WaitForSingleObject(threadHandle, INFINITE); 
    WaitForSingleObject(threadHandle2, INFINITE); 

    cout<<endl<<endl; 

    CloseHandle(mutexHandle); 

    system("pause"); 

    return 0; 

} 

所以我的问题是:为什么设置睡眠0无效互斥代码。

回答

1

请注意您的打印语句不受互斥锁保护,因此一个线程可以自由打印,而另一个线程可以自由修改。通过不睡觉,您可以让调度程序根据线程的数量确定打印顺序。

有些事情不对:

1)你不应该保留的锁内睡觉。这几乎是不正确的。 2)任何你的数据共享的地方,你应该用锁来守护。这意味着打印语句也应该处于锁定状态。

+0

好的很好,thanx圣哈辛托。我把睡眠从锁中取出,并将打印语句包含在锁中。很好地工作,并使得更多的意义! – 2012-04-13 19:24:21

1

此外,作为未来使用互斥的提示,在Windows上,最好的usermode互斥体是SRWLock,接着是CriticalSection。使用基于句柄的同步对象要慢得多。