windows下的线程的同步

MFC CreateEvent()函数自己理解整理 当一个手动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至明确调用ResetEvent函数将其置为无符号状态。 多个进程可持有同一个事件对象的多个句柄,可以通过使用此对象来实现进程间的同步。 一个Event被创建以后,可以用CreateEvent()API来获得它的Handle,用CloseHandle()来关闭它(析构函数),用SetE... 阅读详情

 

  虽然多线程能给我们带来好处,但是也有不少问题需要解决。例如,对于像磁盘驱动器这样独占性系统资源,由于线程可以执行进程的任何代码段,且线程的运行是由系统调度自动完成的,具有一定的不确定性,因此就有可能出现两个线程同时对磁盘驱动器进行操作,从而出现操作错误;又例如,对于银行系统的计算机来说,可能使用一个线程来更新其用户数据库,而用另外一个线程来读取数据库以响应储户的需要,极有可能读数据库的线程读取的是未完全更新的数据库,因为可能在读的时候只有一部分数据被更新过。

  使隶属于同一进程的各线程协调一致地工作称为线程的同步。MFC提供了多种同步对象,下面我们只介绍最常用的四种:

  • 临界区(CCriticalSection)
  • 事件(CEvent)
  • 互斥量(CMutex)
  • 信号量(CSemaphore)
     

通过这些类,我们可以比较容易地做到线程同步。

A、使用 CCriticalSection 类

  当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。

CCriticalSection类的用法非常简单,步骤如下:
 

  1. 定义CCriticalSection类的一个全局对象(以使各个线程均能访问),如CCriticalSection critical_section;
  2. 在访问需要保护的资源或代码之前,调用CCriticalSection类的成员Lock()获得临界区对象:
    critical_section.Lock();
    
    在线程中调用该函数来使线程获得它所请求的临界区。如果此时没有其它线程占有临界区对象,则调用Lock()的线程获得临界区;否则,线程将被挂起,并放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。
  3. 访问临界区完毕后,使用CCriticalSection的成员函数Unlock()来释放临界区:
    critical_section.Unlock();
    
    再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其它线程(B)正在执行critical_section.Lock();语句后且critical_section. Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句,线程A才会继续执行。

下面再通过一个实例进行演示说明。


例程8 MultiThread8

  1. 建立一个基于对话框的工程MultiThread8,在对话框IDD_MULTITHREAD8_DIALOG中加入两个按钮和两个编辑框控件,两个按钮的ID分别为IDC_WRITEW和IDC_WRITED,标题分别为“写‘W’”和“写‘D’”;两个编辑框的ID分别为IDC_W和IDC_D,属性都选中Read-only;
  2. 在MultiThread8Dlg.h文件中声明两个线程函数:
    UINT WriteW(LPVOID pParam);
    UINT WriteD(LPVOID pParam);
    
  3. 使用ClassWizard分别给IDC_W和IDC_D添加CEdit类变量m_ctrlW和m_ctrlD;
  4. 在MultiThread8Dlg.cpp文件中添加如下内容:

    为了文件中能够正确使用同步类,在文件开头添加:
    #include "afxmt.h"
    
    定义临界区和一个字符数组,为了能够在不同线程间使用,定义为全局变量:
    CCriticalSection critical_section;
    char g_Array[10];
    
    添加线程函数:
    UINT WriteW(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	critical_section.Lock();
    	//锁定临界区,其它线程遇到critical_section.Lock();语句时要等待
    	//直至执行critical_section.Unlock();语句
    	for(int i=0;i<10;i++)
    	{
    		g_Array[i]=''W'';
    	    pEdit->SetWindowText(g_Array);
    		Sleep(1000);
    	}
    	critical_section.Unlock();
    	return 0;
    
    }
    
    UINT WriteD(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	critical_section.Lock();
    	//锁定临界区,其它线程遇到critical_section.Lock();语句时要等待
    	//直至执行critical_section.Unlock();语句
    	for(int i=0;i<10;i++)
    	{
    		g_Array[i]=''D'';
    	    pEdit->SetWindowText(g_Array);
    		Sleep(1000);
    	}
    	critical_section.Unlock();
    	return 0;
    
    }
  5. 分别双击按钮IDC_WRITEW和IDC_WRITED,添加其响应函数:
    void CMultiThread8Dlg::OnWritew() 
    {
    	CWinThread *pWriteW=AfxBeginThread(WriteW,
    		&m_ctrlW,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteW->ResumeThread();
    }
    
    void CMultiThread8Dlg::OnWrited() 
    {
    	CWinThread *pWriteD=AfxBeginThread(WriteD,
    		&m_ctrlD,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteD->ResumeThread();
    	
    }
    由于代码较简单,不再详述。编译、运行该例程,您可以连续点击两个按钮,观察体会临界类的作用。

B、使用 CEvent 类

  CEvent 类提供了对事件的支持。事件是一个允许一个线程在某种情况发生时,唤醒另外一个线程的同步对象。例如在某些网络应用程序中,一个线程(记为A)负责监听通讯端口,另外一个线程(记为B)负责更新用户数据。通过使用CEvent 类,线程A可以通知线程B何时更新用户数据。每一个CEvent 对象可以有两种状态:有信号状态和无信号状态。线程监视位于其中的CEvent 类对象的状态,并在相应的时候采取相应的操作。
  在MFC中,CEvent 类对象有两种类型:人工事件和自动事件。一个自动CEvent 对象在被至少一个线程释放后会自动返回到无信号状态;而人工事件对象获得信号后,释放可利用线程,但直到调用成员函数ReSetEvent()才将其设置为无信号状态。在创建CEvent 类的对象时,默认创建的是自动事件。 CEvent 类的各成员函数的原型和参数说明如下:

1、CEvent(BOOL bInitiallyOwn=FALSE,
          BOOL bManualReset=FALSE,
          LPCTSTR lpszName=NULL,
          LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);

 

  • bInitiallyOwn:指定事件对象初始化状态,TRUE为有信号,FALSE为无信号;
  • bManualReset:指定要创建的事件是属于人工事件还是自动事件。TRUE为人工事件,FALSE为自动事件;
  • 后两个参数一般设为NULL,在此不作过多说明。
2、BOOL CEvent::SetEvent();

  将 CEvent 类对象的状态设置为有信号状态。如果事件是人工事件,则 CEvent 类对象保持为有信号状态,直到调用成员函数ResetEvent()将 其重新设为无信号状态时为止。如果CEvent 类对象为自动事件,则在SetEvent()将事件设置为有信号状态后,CEvent 类对象由系统自动重置为无信号状态。

如果该函数执行成功,则返回非零值,否则返回零。

3、BOOL CEvent::ResetEvent();

  该函数将事件的状态设置为无信号状态,并保持该状态直至SetEvent()被调用时为止。由于自动事件是由系统自动重置,故自动事件不需要调用该函数。如果该函数执行成功,返回非零值,否则返回零。我们一般通过调用WaitForSingleObject函数来监视事件状态。前面我们已经介绍了该函数。由于语言描述的原因,CEvent 类的理解确实有些难度,但您只要通过仔细玩味下面例程,多看几遍就可理解。

例程9 MultiThread9

  1. 建立一个基于对话框的工程MultiThread9,在对话框IDD_MULTITHREAD9_DIALOG中加入一个按钮和两个编辑框控件,按钮的ID为IDC_WRITEW,标题为“写‘W’”;两个编辑框的ID分别为IDC_W和IDC_D,属性都选中Read-only;
  2. 在MultiThread9Dlg.h文件中声明两个线程函数:
    UINT WriteW(LPVOID pParam);
    UINT WriteD(LPVOID pParam);
    
  3. 使用ClassWizard分别给IDC_W和IDC_D添加CEdit类变量m_ctrlW和m_ctrlD;
  4. 在MultiThread9Dlg.cpp文件中添加如下内容:

    为了文件中能够正确使用同步类,在文件开头添加

    #include "afxmt.h"
    
    定义事件对象和一个字符数组,为了能够在不同线程间使用,定义为全局变量。
    CEvent eventWriteD;
    char g_Array[10];
    
    添加线程函数:
    UINT WriteW(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	for(int i=0;i<10;i++)
    	{
    		g_Array[i]=''W'';
    	    pEdit->SetWindowText(g_Array);
    		Sleep(1000);
    	}
    	eventWriteD.SetEvent();
    	return 0;
    
    }
    UINT WriteD(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	WaitForSingleObject(eventWriteD.m_hObject,INFINITE);
    	for(int i=0;i<10;i++)
    	{
    		g_Array[i]=''D'';
    	    pEdit->SetWindowText(g_Array);
    		Sleep(1000);
    	}
    	return 0;
    
    }
    
      仔细分析这两个线程函数, 您就会正确理解CEvent 类。线程WriteD执行到 WaitForSingleObject(eventWriteD.m_hObject,INFINITE);处等待,直到事件eventWriteD为有信号该线程才往下执行,因为eventWriteD对象是自动事件,则当WaitForSingleObject()返回时,系统自动把eventWriteD对象重置为无信号状态。
  5. 双击按钮IDC_WRITEW,添加其响应函数:
    void CMultiThread9Dlg::OnWritew() 
    {
    	CWinThread *pWriteW=AfxBeginThread(WriteW,
    		&m_ctrlW,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteW->ResumeThread();
    
    	CWinThread *pWriteD=AfxBeginThread(WriteD,
    		&m_ctrlD,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteD->ResumeThread();
    	
    }
    编译并运行程序,单击“写‘W’”按钮,体会事件对象的作用。

C、使用CMutex 类

  互斥对象与临界区对象很像.互斥对象与临界区对象的不同在于:互斥对象可以在进程间使用,而临界区对象只能在同一进程的各线程间使用。当然,互斥对象也可以用于同一进程的各个线程间,但是在这种情况下,使用临界区会更节省系统资源,更有效率。

D、使用CSemaphore 类

  当需要一个计数器来限制可以使用某个线程的数目时,可以使用“信号量”对象。CSemaphore 类的对象保存了对当前访问某一指定资源的线程的计数值,该计数值是当前还可以使用该资源的线程的数目。如果这个计数达到了零,则所有对这个CSemaphore 类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零时为止。一个线程被释放已访问了被保护的资源时,计数值减1;一个线程完成了对被控共享资源的访问时,计数值增1。这个被CSemaphore 类对象所控制的资源可以同时接受访问的最大线程数在该对象的构建函数中指定。

CSemaphore 类的构造函数原型及参数说明如下:

CSemaphore (LONG lInitialCount=1,
            LONG lMaxCount=1,
            LPCTSTR pstrName=NULL,
            LPSECURITY_ATTRIBUTES lpsaAttributes=NULL);
  • lInitialCount:信号量对象的初始计数值,即可访问线程数目的初始值;
  • lMaxCount:信号量对象计数值的最大值,该参数决定了同一时刻可访问由信号量保护的资源的线程最大数目;
  • 后两个参数在同一进程中使用一般为NULL,不作过多讨论;

  在用CSemaphore 类的构造函数创建信号量对象时要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时,则说明当前占用资源的线程数已经达到了所允许的最大数目,不能再允许其它线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源数加1。

下面给出一个简单实例来说明 CSemaphore 类的用法。

例程10 MultiThread10

  1. 建立一个基于对话框的工程MultiThread10,在对话框IDD_MULTITHREAD10_DIALOG中加入一个按钮和三个编辑框控件,按钮的ID为IDC_START,标题为“同时写‘A’、‘B’、‘C’”;三个编辑框的ID分别为IDC_A、IDC_B和IDC_C,属性都选中Read-only;
  2. 在MultiThread10Dlg.h文件中声明两个线程函数:
    UINT WriteA(LPVOID pParam);
    UINT WriteB(LPVOID pParam);
    UINT WriteC(LPVOID pParam); 
  3. 使用ClassWizard分别给IDC_A、IDC_B和IDC_C添加CEdit类变量m_ctrlA、m_ctrlB和m_ctrlC;
  4. 在MultiThread10Dlg.cpp文件中添加如下内容:

    为了文件中能够正确使用同步类,在文件开头添加:

    #include "afxmt.h"
    
    定义信号量对象和一个字符数组,为了能够在不同线程间使用,定义为全局变量:
    CSemaphore semaphoreWrite(2,2); //资源最多访问线程2个,当前可访问线程数2个 
    char g_Array[10]; 

    添加三个线程函数:

    UINT WriteA(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);
    	CString str;
    	for(int i=0;i<10;i++)
    	{
            pEdit->GetWindowText(str);
    		g_Array[i]=''A'';
    		str=str+g_Array[i];
    	    pEdit->SetWindowText(str);
    		Sleep(1000);
    	}
    	ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);
    	return 0;
    
    }
    UINT WriteB(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);
    	CString str;
    	for(int i=0;i<10;i++)
    	{
    
            pEdit->GetWindowText(str);
    		g_Array[i]=''B'';
    		str=str+g_Array[i];
    	    pEdit->SetWindowText(str);
    		Sleep(1000);
    	}
    	ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);
    	return 0;
    
    }
    UINT WriteC(LPVOID pParam)
    {
    	CEdit *pEdit=(CEdit*)pParam;
    	pEdit->SetWindowText("");
    	WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);
    	for(int i=0;i<10;i++)
    	{
    		g_Array[i]=''C'';
    	    pEdit->SetWindowText(g_Array);
    		Sleep(1000);
    	}
    	ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);
    	return 0;
    
    }
    
    这三个线程函数不再多说。在信号量对象有信号的状态下,线程执行到WaitForSingleObject语句处继续执行,同时可用线程数减1;若线程执行到WaitForSingleObject语句时信号量对象无信号,线程就在这里等待,直到信号量对象有信号线程才往下执行。
  5. 双击按钮IDC_START,添加其响应函数:
    void CMultiThread10Dlg::OnStart() 
    {
    	CWinThread *pWriteA=AfxBeginThread(WriteA,
    		&m_ctrlA,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteA->ResumeThread();
    
    	CWinThread *pWriteB=AfxBeginThread(WriteB,
    		&m_ctrlB,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteB->ResumeThread();
    
    	CWinThread *pWriteC=AfxBeginThread(WriteC,
    		&m_ctrlC,
    		THREAD_PRIORITY_NORMAL,
    		0,
    		CREATE_SUSPENDED);
    	pWriteC->ResumeThread();
    
    	
    }
    
MFC多线程同步 MFC提供了多种同步对象,下面我们只介绍最常用的四种: 1、临界区(CCriticalSection) 2、事件(CEvent) 3、互斥量(CMutex) 4、信号量(CSemaphore) 一、临界区 使用CCriticalSection类。是一个用于同步的对象,同一时刻只允许一个线程存取资源或代码区。临界区在控制一次只有一个线程修改数据或其它的控制资源时非常有用。 class CCriticalSection... 阅读详情

相关推荐

C++中使用CEvent进行线程事件信号和线程同步

在C++中,线程同步是一项重要的任务,以确保多个线程能够正确地协调和交互。在本文中,我们将详细介绍如何在C++中使用CEvent进行线程事件信号和线程同步。在C++中,线程同步是一项重要的任务,以确保多个线程能够正确地协调和交互。在本文中,我们将详细介绍如何在C++中使用CEvent进行线程事件信号和线程同步。通过使用CEvent类,我们可以在C++中使用CEvent进行线程事件信号和线程同步。当线程2设置事件后,线程1将收到事件,并继续执行。当线程2设置事件后,线程1将收到事件,并继续执行。

TechProX的博客 476

多线程编程之四——线程同步

多线程编程之四——线程同步作者:韩耀旭下载源代码八、线程同步  虽然多线程能给我们带来好处,但是也有不少问题需要解决。例如,对于像磁盘驱动器这样独占性系统资源,由于线程可以执行进程的任何代码段,且线程的运行是由系统调度自动完成的,具有一定的不确定性,因此就有可能出现两个线程同时对磁盘驱动器进行操作,从而出现操作错误;又例如,对于银行系统的计算机来说,可能使用一个线程来更新其用户数据

michaelpp的专栏 1229

windows线程同步总结

线程 1)如果你正在编写C/C++代码,决不应该调用CreateThread。相反,应该使用VisualC++运行期库函数_beginthreadex,退出也应该使用_endthreadex。如果不使用Microsoft的VisualC++编译器,你的编译器供应商有它自己的CreateThred替代函数。不管这个替代函数是什么,你都必须使用。 2)因为_beginthreadex和

h a 6 6 6 c k 为 你解决复杂难题! 589

CEvent类在线程同步中的作用

CEvent是用于线程间通信的一个封装类,他继承于CSyncObject,而CSyncObject又继承与类之父Cobject CEvent是一个允许一个线程在某种情况发生时,唤醒另外一个线程同步对象 使用 CEvent 类2007-07-10 19:44使用 CEvent 类   CEvent 类提供了对事件的支持。事件是一个允许一个线程在某种情况发生时,唤醒另外一个线程同步对象。例

wscxr57的专栏 1155

Windows线程基本知识和线程同步

Windows-线程基本知识及线程同步

Coderwind的博客 1815

Windows线程开发】Windows线程同步技术

我们在上一章节中讲解了关于Windows线程基础,相信大家已经对线程有了基本的概念。这一章节中,我们来讲讲线程同步技术,包括加锁技术(原子锁和互斥体)和事件,信号灯。

WdIg-2023的博客 2371

Windows线程同步总结

Windows线程同步 Windows线程同步可以利用互斥对象来实现,也可以使用事件对象,关键代码段来实现。 1 事件对象实现线程同步 Event对象创建函数          事件对象的创建事件对象属于内核对象,它包含以三个成员:使用计数,是否是自动重置还是人工重置的布尔值,通知状态的布尔值。 HANDLE CreateEvent( LPSECURITY_ATTRI

eskimoer的专栏 1350

windows 线程同步

最近面试被问到Windows下的线程同步,有的地方记不清了,只好把老视频找出来,对照整理一下。 一、原子操作 1、InterlockedIncrement: 加1操作; 2、InterlockedDecrement: 减1操作; 3、InterlockedExchangeAdd: 加上指定的值,也可以加上一个负数; 4、InterlockedExchange、InterlockedExchangePointe: 能够以原子操作的方式用第二个参数的值取代第一个参数的值; 二、临界区域 Critic

jyzeng1989的博客 396

Windows线程同步

以下内容摘抄自《Visual C++开发技术大全》,为学习笔记。

936

Windows 下的线程同步

<br />这段时间一直在做Windows下的项目开发, 最近花了点时间翻了翻书, 总结一下Windows常用的线程同步方法.<br /> <br /><br /><br />一、线程同步--SendMessage()<br /> 1. SendMessage()是一种简单方便的窗口和工作者线程间的数据同步的方法<br /> 2. 当工作者线程将数据准备好后,可以通过调用SendMessage()将消息发送给指定的窗口,这时发送线程将被阻塞直到SendMessage()返回. <br /><br />

DennisZhangX的专栏 956

Windows 下 C++ 线程同步与异步有哪些方式

方法所属是否跨平台是否推荐应用场景std::mutexlock_guardC++ 标准库✅ 是✅ 推荐通用同步C++ 标准库✅ 是✅ 推荐原子操作C++ 标准库✅ 是✅ 推荐条件等待❌ 否✅ 推荐Windows 内部同步Event❌ 否✅ 推荐线程通知std::asyncC++ 标准库✅ 是✅ 推荐异步任务C++ 标准库✅ 是✅ 推荐自定义异步任务IOCP❌ 否✅ 推荐高性能网络/文件。

h a 6 6 6 c k 为 你解决复杂难题! 325

windows线程同步的几种方式

windows线程同步的方式主要有四种:互斥对象、事件对象、信号量以及关键代码段

八块吮指原味鸡的博客 2124

windows下主线程同步

windows线程同步方式 PostMessage、SendMessage、PostThreadMessage方式 Event方式,SetEvent、ResetEvent、WaitForMultipleObjects 临界区 信号量 子线程与主线程之间的异步、同步回调方式 借助windows窗口,在主线程中注册回调事件,子线程通过postmessage方式发送给该窗口,从而实现消息通知。 实...

WeinKee的博客 410

操作系统实验之Windows中的线程线程同步现象

3.观察两个线程执行后的情况,可以发觉最后 i 的值不一定是 0, 有时是很大的正数,有时是很大的负数,这就是多个线程在操作同一个变量 i时,未同步时带来的严重问题。实验结果可能显示 i 的值为很大的正数、很大的负数或零附近的某个值,这取决于线程调度的具体方式和时机。由于加 1 和减 1 操作的数量相等,且这些操作是同步进行的,因此最终 i 的值将始终为 0。加入的同步代码的两个线程,无论如何执行,i 的值总是 0 ,结果是正确的。在包含同步代码的版本中,使用了临界区来确保对 i 的访问是互斥的。

m0_74107848的博客 631

Windows线程同步API

本文主要总结创建、结束线程和WIN32 API提供的一些线程同步方法。同步方法包括用户态同步方式:InterLock、CriticalSection、SRWLock和内核态同步方式:Event、Semaphore、Mutex等。本文通过简单的例子演示API的使用,没有包含原理的说明,假定读者具有其他语言或者平台的并发编程经验。 创建、结束线程 WIN32 API虽然提供了CreateThead

SzMing 555

Windows中的线程同步

lpCriticalSection Init函数中传入需要初始化的CRITICAL_SECTION对象的地址值,反之Delete函数传入需要接触的CRITICAL_SECTION对象的地址值。

m0_61886762的博客 1268

Windows常用的几种线程同步技术

Windows常用的几种线程同步技术。 当 有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源。例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中 的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当作是互不相干的任务分 别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作。 存在一些线程同步地址的问题,Win32提供了许多线程同步的方式。在本..

thanklife的专栏 1507

Windows API笔记(三)线程同步

Windows API笔记(一)内核对象 Windows API笔记(二)进程和进程间通信、进程边界 Windows API笔记(三)线程线程同步线程局部存储 Windows API笔记(三)线程同步 Windows API笔记(四)win32内存结构 Windows API笔记(五)虚拟内存 Windows API笔记(六)内存映射文件 Windows API笔记(七)堆 Windows A...

David 974
上一篇: 网游服务端结构设计
下一篇: Ogre的MaterialSystem分析
bisword
博客等级 码龄25年 96粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值