Win32 多线程
专注的流浪猫
这个作者很懒,什么都没留下…
展开
-
Win32多线程之进程
从win32的角度来看,进程含有内存和资源。资源包括核心对象(如文件Handles 和线程),USER资源(如对话框和字符串),GDI资源(如设备上下文和画刷)。进程就像一本活页笔记夹,你可以在其中的活页上写东西,也可以擦掉内容或甚至整页撕掉,活页笔记夹只是持有那些东西而已。进程本身并不执行,它只是提供一个安置内存和线程的地方。内存:每个进程都关系到内存。内存就像是前面所说的活页笔记夹转载 2013-10-21 23:30:40 · 473 阅读 · 0 评论 -
Win32多线程之临界区(Critical Sections)
Win32之中最容易使用的一个同步机制就是 critical sections。所谓critical sections意思是指一小块“用来处理一份呗共享的资源”的程序代码。这里所谓的资源,并不是指.res(资源文件)的Windows资源,而是广义上地指一块内存,一个数据结构,一个文件,或任何其他具有“使用之排他性”的东西。也就是说,“资源”每一次(同一时间内)只能够被一个线程处理。 你可能必转载 2013-11-22 23:37:52 · 1492 阅读 · 0 评论 -
Win32多线程之互斥器(Mutexes)
Win32的Mutex用途和critical section非常类似,但是它牺牲速度以增加弹性,或许你已经猜到了。mutex 是MUTual EXclusion的缩写。一个时间内只能够有一个线程拥有mutex,就好像同一时间内只能够有一个线程进入同一个critical section一样。 虽然mutex和critical section做同样的事情,但是它们的运作还是有差别的: 1)转载 2013-11-23 15:42:12 · 1263 阅读 · 0 评论 -
Win32多线程之死锁(DeadLock)
为每一个链表(linked list)准备一个critical section之后(关于链表,请参看”Win32多线程之临界区(Critical Sections)“),我却开始了另一个问题。请看下面这个用来交换两个链表内容的函数:void SwapLists(List *listA, List * listB){ List *tmp_list; Ente转载 2013-11-23 00:46:07 · 898 阅读 · 0 评论 -
Win32多线程之最小锁定时间
在任何关于同步机制的讨论中,不论是在Win32或Unix或其他操作系统,你一定会一再地听到这样一条规则: 不要长时间锁住一份资源 如果你一直让资源被锁定,你就会阻止其他线程的执行,并把整个程序带到一个完全停止的状态。以critical sectin 来说,当某个线程进入critical section时,该项资源即被锁定。 我们很难定义所谓”长时间“是多少,如果你在网络转载 2013-11-23 00:18:10 · 658 阅读 · 0 评论 -
Win32多线程之同步控制
写多线程程序的一个最具挑战性的问题就是,如何让一个线程和另一个线程合作。除非你让它们同心协力。否则必然会出现“race conditions”(竞争条件)和“data corrupton”(数据被破坏)的情况。 在典型的办公室文化中,协调工作是由管理者来执行的。类似的解决方案,也就是“让某个线程成为大家的老板”。当然可以在软件中实现出来,但是每逢它们需要指挥时,就要它们排队等待,其实有着转载 2013-11-21 22:44:15 · 659 阅读 · 0 评论 -
Win32多线程之WaitForMultipleObjects
Win32函数中的WaitForMultipleObjects()允许你在同一时间等待一个以上的对象。你必须将一个由handles组成的数组交给此函数,并指定要等待其中一个对象或是全部的对象,下面就是这个函数的原型:DWORD WaitForMultipleObjects(DWORD nCount,const HANDLE* lpHandles,BOOL bWa转载 2013-11-21 21:54:37 · 1779 阅读 · 0 评论 -
Win32多线程之标准消息循环
Windows程序中的标准消息循环看起来如下所示:while(GetMessage(&msg, NULL, 0, 0) ){ TranslateMessage(&msg); DispatchMessage(&msg);} GetMessage()有点像是特殊版本的WaitForSingleObject(),它等待消息而不是核转载 2013-11-21 22:27:00 · 1209 阅读 · 0 评论 -
Win32多线程之被激发的对象(Signaled Objects)
核心对象在“Win32多线程之核心对象”已经讲过,如文件,进程,互斥器(Mutexes)等。这些对象的状态都可能是线程关心的东西。信号量(semaphores)和互斥器(mutexes)可以记录红绿灯状态,文件对象可以告诉我们一个I/O操作何时完成。线程对象则可以告诉我们它何时结束(当线程结束时,它出于激发状态)。 线程可以使用像WaitForSingleobject()这样的转载 2013-11-20 21:57:23 · 926 阅读 · 0 评论 -
Win32多线程之线程等待
等待是线程常常需要做的事情。当你读取用户的输入,或是存取磁盘文件时,你的线程必须等待因为磁盘存取速度和用户输入动作的速度是CPU速度的百万(甚至)分之一。等待是线程的一种必要之恶。 等待技术: 1.Win32 Sleep()函数。这个函数要求操作系统终止线程动作,直到渡过某个指定时间之后才恢复。虽然很简单,但好似实际上你却不可能事先知道什么事情要等待多久。即使一个可以快速完成转载 2013-11-19 22:55:15 · 1006 阅读 · 0 评论 -
Win32多线程之信号量(Semaphores)
信号量是解决各种生产者/消费者问题的关键要素。这种问题会存在一个缓冲区,可能在同一时间内被读出数据或被写入数据。 Win32中的一个semaphore可以被锁住最多n次,其中n是semaphore被产生时指定的。n常常被设计用来代表“可以锁住一份资源”的线程个数,不过并非单独一个线程就不能够拥有所有的锁定,这没什么理由可言。 理论上可以证明,mutex是semaphore的一种退转载 2013-11-24 21:45:08 · 1061 阅读 · 0 评论 -
Win32多线程之我需要锁定数据吗?
很多人不知道如何决定数据是否需要保护,使用同步机制会使程序效率降低,而且它们也不容易使用,但是在某些情况下又非用不可。下面是一些指导方针: 1) 如果你不确定,那么你或许需要一个锁定; 2) 如果你在一个以上的线程中使用同一块数据,那么你必须保护它。我所谓的“使用”,一般而言包括读取,与之作比较,写入,更新,改变,或任何其他操作,只要会用到变量 名称的都算;转载 2013-12-08 12:42:09 · 620 阅读 · 0 评论 -
Win32多线程之volatile
我相信你一定遇到这样的问题:你把某人的名字和电话号码写到你的通讯录中,数个月之后企图打电话给这个人,却发现资料已经过期了。同样的情况也可能发生在编译器为你产生的程序代码中。 编译器最优化的结果是,设法把常用的数据放在CPU的内部寄存器中,这些寄存器就像你的通讯录一样,数据从寄存器中读出,远比从内存中读出快得多,就好像使你从你的通讯录中读数据,远比从大电话簿中读数据要快得多,当然,如果另一个转载 2013-12-07 17:52:15 · 732 阅读 · 0 评论 -
Win32多线程之线程优先级层次
线程的优先级层次(Priority Level)是对进程的优先权类别的一个修改,使你能够调整同一个进程内的各线程的相对重要性。一共有七种优先权等级,如下表所示:优先级层次调整值THREAD_PRIORITY_HIGHEST+2THREAD_PRIORITY_ABOVE_NORMAL+1THREAD_PRIORITY_NORMAL转载 2013-12-07 16:11:45 · 721 阅读 · 0 评论 -
Win32多线程之线程优先级
Win32中优先权的概念,用来决定下一个获得CPU时间的线程是谁,较高优先权的线程必然获得较多的CPU时间。关于优先权的完整讨论其实相当复杂,你可以无分轩轾地给予每一个线程相同的优先权,这可能会使你承担不少麻烦,你也可以明智地使用优先权,使自己能够调整程序的执行次序。例如你可以设定你的GUI线程有较高优先权,使它对于用户的反应能够比较平顺一些,或者你可以改变worker线程的优先权,使它们只在系统转载 2013-12-07 12:22:08 · 1389 阅读 · 0 评论 -
Win32多线程之 利用TerminateThread()放弃一个线程
如果当前工作线程尚未完成,而用户希望终止程序,该怎么办呢?利用TerminateThread()放弃一个线程 这正是Win32程序设计的一般性问题。我如何能够安全地关闭任何执行中的线程呢?最明显的答案就是利用TerminateThread(). BOOL TerminateThread( HANDLE hThread, DWORD dwExitCod转载 2013-12-01 12:42:08 · 3545 阅读 · 0 评论 -
Win32多线程之同步机制摘要
Critical Section Critical Section(临界区)用来实现“排他性占有”。适用范围是单一进程的各线程之间。它是: 1)一个局部性对象,不是一个核心对象; 2)快速而由效率。 3)不能够同时有一个以上的critical section被等待; 4)无法侦测是否已被某个转载 2013-11-28 22:40:17 · 500 阅读 · 0 评论 -
Win32多线程之Interlocked Variables
同步机制的最简单类型就是使用interlocked 函数,对着标准的32位变量进行操作。这些函数并没有提供“等待”机能,它们只是保证对某个特定变量的存取操作时“一个一个按顺序来”。 考虑一下,如果你需要维护一个32位计数器的“排他性 存取”性质,你该怎么做?你可能会产生一个critical section或一个mutex,拥有它,然后进行你的操作,然后再释放拥有权,一个32位变量的存取操作只转载 2013-11-28 22:22:37 · 749 阅读 · 0 评论 -
Win32多线程之事件(Event Objects)
Win32中最具弹性的同步机制就属events对象了。Event是一种核心对象, 他的唯一目的就是成为激发状态或者未激发状态。这两种状态完全由程序来控制, 不会成为Wait...()函数的副作用。 Event对象之所以大有用途,正是因为它们的状态完全在你的控制之下。Mutexes和semaphores就不一样了。它们的状态会因WaitForSingleObject()之类转载 2013-11-25 22:20:37 · 2028 阅读 · 0 评论 -
Win32多线程之等待一个线程的结束(WaitForSingleObject)
由于线程停工是操作系统的责任,当然操作系统也有责任让其他线程知道某个线程停工了。 Win32提供了一个名为WaitForSingleObject()的函数。他的第一个参数是个核心对象(如线程)的handle,为了方便讨论,我把即将等待的线程称为线程#1,把正在执行的线程称为线程#2。刚刚说的“线程核心对象”指的是线程#2。 调用WaitForSingleObject()并放置一个“线转载 2013-11-20 21:31:18 · 1945 阅读 · 0 评论 -
Win32多线程之性能监视器
Windows系统任务管理器中,”性能“属性页中,可以查看CPU和内存的使用情况。它因此成为了一个重要的工具,用以确定我们所写的程序有预期的行为。当你启动一个程序时,如果CPU的利用率达到100%并且在该处停留很久,这就说明你的程序可能有个busy loop。转载 2013-11-19 23:09:43 · 770 阅读 · 0 评论 -
Win32多线程之为什么不使用多进程
人们一旦接触到线程,他们最常问的问题就是:有什么是线程能够给我而多进程所不能给我的?言下之意就是,线程又怎么样!最重要的答案便是:线程价廉,线程启动比较快,退出比较快,对系统资源的冲击也比较小,而且,线程彼此分享了大部分核心对象(如 file handles)的拥有权。 如果使用多重进程,最困难的问题大概是:如何把窗口的handle交给另一个进程,在Win32中,handle只在其诞生地(转载 2013-11-03 12:10:22 · 1258 阅读 · 0 评论 -
Win32多线程之线程的优缺点
使用线程并非没有代价,使用线程可能会引发数个潜在的严重的问题。除非经过小心设计,多线程程序有着不可预期,测试困难的倾向。 如果你曾经在厨房与别人共事过,你知道,有时候人多反而麻烦。如果你们都做同一件事情,你就必须不断和另一个说话,找出什么已经做了什么还没做;如果两个人做完全不同的事情,情况会比较好一些。即使这样,还是会有问题发生,因为厨房的资源有限,你们必须得先计划好,先了解谁用那个器具那转载 2013-11-16 00:58:41 · 762 阅读 · 0 评论 -
Win32多线程之线程之间的通信
线程之间如何通信? 一个和race conditions很有关系的问题就是,线程通信问题。一个线程要有大用途,你i必须告诉它做什么事情。Win32提供了一个简单的方法,供应线程的启动(start-up)信息。但是两个线程间的交谈就十分棘手了,线程怎么知道数据要放在哪里? 最明显的答案就是放在全局变量中。因为所有的线程都可以对它进行读写。但是如果线程A写下一个全局变转载 2013-11-16 00:47:47 · 976 阅读 · 0 评论 -
Win32多线程之原子操作
严密阻止race condition的发生是必要的。 困难点在于鉴定出race condition的发生地点。长时间在高级语言如C/C++之中打滚的你,或许已经忘了CPU是在非常低阶中操作。当你思考race condition时,如果忽略‘’低阶‘这件事,可能会造成难以去除的bug。 一个操作如果能够不受中断地完成,我们称之为(原子操作)atomic operation。转载 2013-11-16 00:39:28 · 1307 阅读 · 0 评论 -
Win32多线程之竞争条件(Race Conditions)
Context switching 是抢先式多任务的心脏。在一个合作型多任务系统中,操作系统必须得到程序的允许才能够改变线程。但是在抢先式多任务系统中,控制权被强制转移,也因此两个线程之间的执行次序变得不可预期,这不可预期性便造成了所谓的race conditions(竞争条件)。转载 2013-11-16 00:32:39 · 714 阅读 · 0 评论 -
Win32多线程之CreateThread
1.CreateThread 产生一个线程(并因而成就一个多线程程序),是以CreateThread()作为一切行动的开始,次函数的原型如下:HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAd转载 2013-11-16 01:37:36 · 4244 阅读 · 0 评论 -
Win32多线程之线程上下文切换(Context Switching)
在一个抢先式多任务系统中,操作系统小心地确保每一个线程都有机会执行。他依赖硬件的协助以及许多的簿记工作。当硬件计时器认为某个线程已经执行够久了,就会发出一个中断,于是CPU取得目前这个线程的当前状态,即把所有寄存器的内容拷贝到堆栈之中,再把它从堆栈拷贝到一个CONTEXT结构(这样便储存了线程的状态)中,以备以后在用。 要切换不谈的线程,操作系统应先切换该线程所隶属的进程的内存转载 2013-11-14 22:07:40 · 1405 阅读 · 0 评论 -
Win32多线程之多线程的特点
1.多线程程序是无法预测其行为的。2.线程的执行顺序无法保证。3.线程对于晓得改变有高度的敏感。4.线程并不总是立即启动。转载 2013-11-16 22:47:26 · 634 阅读 · 0 评论 -
Win32多线程之核心对象
CreateThread()传回两个值,用以识别一个新的线程。第一个值是个Handle, 这也是CreateThread()的返回值,大部分与线程有关的API函数都需要它。第二个值是由lpThreadId带回来的线程ID。线程ID是一个全局变量,可以独一无二地表示系统中任一进程中的某个线程。AttachThreadInput()和PostThreadMessage()就需要用到线程ID,这两转载 2013-11-16 23:38:24 · 813 阅读 · 0 评论 -
Win32多线程之ExitThread
VOID ExitThread(DWORD dwExitCode);dwExitCode: 指定该线程的结束代码返回值: 无返回值。 这个函数有点像C runtime library中的exit()函数。因为它可以在任何时候被调用并且绝不会返回。任何代码放在此行之下,保证不会被执行。转载 2013-11-18 21:45:24 · 1007 阅读 · 0 评论 -
Win32多线程之设计多线程程序需要注意的问题
1.简单和安全大于复杂和速度;程序与线程的关系越紧密,越容易产生错误并引起race condition。转载 2013-11-19 22:32:24 · 583 阅读 · 0 评论 -
Win32多线程之后台线程
后台线程和主线程完全分开。它使用不同的数据结构,并且是非交谈式的。任何东西如果要画在屏幕上,都必须送出一个消息给主线程(GUI线程),告诉它去做这件事情。转载 2013-11-19 22:37:19 · 737 阅读 · 0 评论 -
Win32多线程之主线程
主线程: 程序启动后就执行的那个线程称为主线程(primary thread)。主线程有两个特点: 第一,它不许负责GUI(Graphic User Interface)程序中的主消息循环; 第二,这一线程结束(不论是因为返回或因为调用了ExitThread())会使得程序中的所有线程都被迫结束。程序也因此而结束,其它线程没有机会做清理工作。 这是C r转载 2013-11-18 21:58:57 · 948 阅读 · 0 评论 -
Win32多线程之GetExitCodeThread
BOOL GetExitCodeThread( HANDLE hThread, LPDWORD lpExitCode);参数hThread :由CreateThread()传回的线程handlelpExitCode:指向一个DWORD, 用以接收结束代码(exit code)返回值: 如果成功,GetExitCodeThread()传回TRUE,否转载 2013-11-18 21:38:35 · 1811 阅读 · 2 评论 -
Win32多线程之微软的多线程模型
Win32说明文件一再强调线程分为GUI线程和worker线程两种。GUI线程负责建造窗口以及处理主消息循。worker线程负责执行纯粹的运算工作,如重新计算或重新编页等等,它们会导致主线程的消息队列失去反应,一般而言,GUI线程绝对不会去做哪些不能够马上完成的工作。 GUI线程的定义是:拥有消息队列的线程,任何一个特定窗口的消息总是被产生这一窗口的线程抓到并处理。所有对该窗口的改变也都应转载 2013-11-18 22:16:16 · 806 阅读 · 0 评论 -
Win32多线程之错误处理
经验显示,线程的各种相关函数是错误高危险群,而适当的错误处理可以阻止挫败并产生一个比较可信赖的程序。转载 2013-11-18 22:03:53 · 612 阅读 · 0 评论 -
Win32多线程之线程对象与线程
线程的handle是指向“线程核心对象”,而不是指向线程本身,对大部分API而言,这项差异没什么影响。当你调用CloseHandle()并给予它一个线程handle时,你只不过是表示,你希望自己和次核心对象不再有任何瓜葛。CloseHandle()唯一做的事情就是把引用计数减一。如果该值变成0,对象会自动被操作系统摧毁。 “线程核心对象”引用到的那个线程也会令核心对象开启。因此,线程对象的转载 2013-11-16 23:54:33 · 704 阅读 · 0 评论 -
Win32多线程之多线程设计成功的关键
多线程设计成功的关键是:1.各线程的数据要分离开来,避免使用全局变量;2.不要在线程之间共享GDI对象;3.确保你知道各线程的状态,不要径自结束程序而不等待各个线程的结束;4.让主线程处理用户界面(GUI)。转载 2013-11-18 22:44:51 · 655 阅读 · 0 评论 -
Win32多线程之通过设立标记来结束线程
Win32标准的做法是在你的程序代码中设立一个标记,利用其值来要求线程结束自己。 这个技术有十分明显的优点,可以保证目标线程在结束之前有安全而一致的状态。其缺点也十分明显:线程需要一个polling机制,时时检查标记值是否为空,以决定是否要结束自己。我们所说的polling机制是指:用手动重置(manual-reset)的event对象。Worker线程可以检查该event对象的状态或是等待它转载 2013-12-07 11:38:35 · 650 阅读 · 0 评论