⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 11.txt

📁 VC++技术内幕精讲
💻 TXT
📖 第 1 页 / 共 2 页
字号:
DWORD SuspendThread( );
//Return Value:The thread’s previous suspend count if successful; 0xFFFFFFFF otherwise. 
//CWinThread::SuspendThread:Increments the current thread’s suspend(悬挂,延缓) count. If any thread has a suspend count above zero, that thread does not execute.
3)恢复线程运行:
CWinThread::ResumeThread
DWORD ResumeThread( );
//Return Value:The thread’s previous suspend count if successful; 0xFFFFFFFF otherwise. If the return value is zero, the current thread was not suspended. If the return value is one, the thread was suspended, but is now restarted. Any return value greater than one means the thread remains suspended.
//Remarks:Called to resume(恢复) execution of a thread that was suspended(暂停,延缓) by the SuspendThread member function, or a thread created with the CREATE_SUSPENDED flag. The suspend count of the current thread is reduced by one. If the suspend count is reduced to zero, the thread resumes execution; otherwise the thread remains suspended.
4)创建辅助线程事例:
UINT MyThreadProc( LPVOID pParam )
{
    CMyObject* pObject = (CMyObject*)pParam;
    if (pObject == NULL ||
        !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
    return 1;   // if pObject is not valid
    // do something with 'pObject'
    return 0;   // thread completed successfully
}
// inside a different function in the program
...
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);

3,主线程 和 辅助线程 的通话:(这里的主线程指应用程序,是个用户界面线程)
1)最简单的方法:使用全局变量。
(注意:如书上事例B中在一个辅助线程中使用全局的计数器,不希望其它现在在计数器递增的时候由于其它线程访问而引起混乱,则将起声明成volatile变量保证计数器不被保存到寄存器中,也可以使用InterlockedIncrement来阻塞其它线程同时使计数器递增。)
补充一:
InterlockedIncrement
LONG InterlockedIncrement(
  LPLONG lpAddend   // pointer to the variable to increment
);
//The InterlockedIncrement function both increments (increases by one) the value of the specified 32-bit variable and checks the resulting value. The function prevents more than one thread from using the same variable simultaneously. 
补充二:
volatile
使用 volatile 修饰符能够确保一个线程检索由另一线程写入的最新值。
//当字段声明中含有 volatile 修饰符时,该声明引入的字段为易失字段。

由于采用了优化技术(它会重新安排指令的执行顺序),在多线程的程序运行环境下,如果不采取同步控制手段,则对于非易失字段的访问可能会导致意外的和不可预见的结果。这些优化可以由编译器、运行时系统或硬件执行。但是,对于易失字段,优化时的这种重新排序必须遵循以下规则: 

读取一个易失字段称为易失读取。易失读取具有“获取语义”;也就是说,按照指令序列,所有排在易失读取之后的对内存的引用,在执行时也一定排在它的后面。 
写入一个易失字段称为易失写入。易失写入具有“释放语义”;也就是说,按照指令序列,所有排在易失写入之前的对内存的引用,在执行时也一定排在它的前面。 
这些限制能确保所有线程都会观察到由其他任何线程所执行的易失写入(按照原来安排的顺序)。一个遵循本规范的实现并非必须做到:使易失写入的执行顺序,在所有正在执行的线程看来都是一样的。易失字段的类型必须是下列类型中的一种: 
引用类型。 

类型 byte、sbyte、short、ushort、int、uint、char、float 或 bool。 
枚举基类型为 byte、sbyte、short、ushort、int 或 uint 的枚举类型。 
(China msdn-C# 语言规范 )

2)不能使用Windows消息(即不能主线程向辅助线程发送消息通信),辅助线程没有窗口没有消息循环。


4,辅助线程 和 主线程(用户界面线程) 通信
1)辅助线程向主线程(用户界面线程)发送Windows消息,由主线程响应该消息,从而实现通信。(主线程有一个窗口,可见或不可见,如果辅助线程可以得到主线程的窗口句柄,便可以向主线程发送Windows消息了。主线程总是有一个消息循环的。)
2)辅助线程可以通过AfxBeginThread函数参数传入主线程句柄从而得到主线程的句柄。
3)辅助线程使用寄出(post)消息。任何用户定义的消息都可以。(使用送出(SEND)消息会引起主线程MFC消息处理代码的重入,这在模式对话框中会出现问题。)


5,EX11B事例说明:
1)CComputeDlg::OnStart函数中,利用AfxBeginThread(ComputeThreadProc, GetSafeHwnd(),THREAD_PRIORITY_NORMAL);函数为用户自定义的全局函数ComputeThreadProc创建辅助线程的同时,利用GetSafeHwnd()获得对话框句柄并做为参数传入
ComputeThreadProc函数形参pParam中。
//GetSafeHwnd() Returns the window handle for a window. Returns NULL if the CWnd is not attached to a window or if it is used with a NULL CWnd pointer. 
2)UINT ComputeThreadProc(LPVOID pParam)函数中利用传进来的参数pParam,调用::PostMessage((HWND) pParam, WM_THREADFINISHED, 0, 0)函数向对话框窗口发送消息用户自定义WM_THREADFINISHED消息。
3)在对话框类中为WM_THREADFINISHED添加控制函数。
三步:
消息控制函数声明:CComputeDlg类头文件 LRESULT OnThreadFinished(WPARAM wParam, LPARAM lParam);消息映射:CComputeDlg类代码文件 ON_MESSAGE(WM_THREADFINISHED, OnThreadFinished)
消息控制函数:CComputeDlg类代码文件 
LRESULT CComputeDlg::OnThreadFinished(WPARAM wParam, LPARAM lParam)
{
 CDialog::OnOK();
 return 0;
}

6,排斥区(CCriticalSection)
MFC提供了CCriticalSection类来帮助我们实现在线程之间共享全局数据(保证对其临界访问).
使用方法下面代码演示:
CCriticalSection g_cs;//定义g_cs为临界访问对象
int g_nCount;
voit func()
{
 g_cs.Lock();
 g_nCount++;
 g_cs.Unlock();
}
说明:
1)CCriticalSection从CSyncObject类派生而来:
An object of class, CCriticalSection represents a "critical section" - a synchronization object that allows one thread at a time to access a resource or section of code. Critical sections are useful when only one thread at a time can be allowed to modify data or some other controlled resource. 
2)构造函数CCriticalSection( )说明:
Constructs a CCriticalSection object. To access or release a CCriticalSection object, create a CSingleLock object and call its Lock and Unlock member functions. If the CCriticalSection object is being used stand-alone, call its Unlock member function to release it.
3)CCriticalSection::Unlock:  Releases the CCriticalSection object. 
CCriticalSection::Lock: Use to gain access to the CCriticalSection object. 
4)进一步使用说明:
当线程A正在执行func()函数使g_nCount++增1的时候,线程B调用func()函数执行到g_cs.Lock()的时候线程B被阻塞直到线程A执行了g_cs.Unlock()才继续往下执行g_nCount++。
5)CCriticalSection只是用于当个进程内的控制访问,如果要在不同的进程之间控制数据的访问需要使用 互斥体(CMutex) 和 信号(semaphore)。


7,互斥体(CMutex)
1)CMutex:
An object of class CMutex represents a “mutex” — a synchronization object that allows one thread mutually exclusive access to a resource. Mutexes are useful when only one thread at a time can be allowed to modify data or some other controlled resource.
2)CMutex类从CSyncObject类派生而来,其一般用法参见下E文:
To use a CMutex object, construct the CMutex object when it is needed. Specify the name of the mutex you wish to wait on, and that your application should initially own it. You can then access the mutex when the constructor returns. Call CSyncObject::Unlock when you are done accessing the controlled resource.


8,信号(CSemaphore)
1)CSemaphore(也是从CSyncObject类派生而来):
An object of class CSemaphore represents a “semaphore” — a synchronization object that allows a limited number of threads in one or more processes to access a resource. A CSemaphore object maintains a count of the number of threads currently accessing a specified resource.
2)Semaphores are useful in controlling access to a shared resource that can only support a limited number of users.The current count of the CSemaphore object is the number of additional users allowed. When the count reaches zero, all attempts to use the resource controlled by the CSemaphore object will be inserted into a system queue and wait until they either time out or the count rises above 0. The maximum number of users who can access the controlled resource at one time is specified during construction of the CSemaphore object.
构造函数:
CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName = NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL );

9,关于从CSyncObject类派生类一些说明:
1)CCriticalSection,CMutex,CSemaphore,CEvent,derived from CSyncObject。
2)CSyncObject类成员中包含一下两成员函数:
Lock   Gains access to the synchronization object. 
Unlock   Releases access to the synchronization object. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -