b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

Windows平台下的多线程编程

电脑杂谈  发布时间:2019-06-18 10:05:52  来源:网络整理

java线程编程_linux线程编程_多线程编程

1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程),线程是进程的基本执行单元,一个进程(程序)的所有任务都程中执行。如果任意一个线程调用了exit或_exit,则整个进程的所有线程都终止,由于从main函数return也相当于调用exit,为了防止新创建的线程还没有得到执行就终止,我们在main函数return之前延时1秒,这只是一种权宜之计,即使主线程等待1秒,内核也不一定会调度新创建的线程执行多线程编程,1.2我们会看到更好的办法。答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径。

Windows是一种多任务的操作系统,在Windows的一个进程内包含一个或多个线程。32位Windows环境下的Win32API提供了多线程应用程序开发所需要的接口函数,而利用VC中提供的标准C库也可以开发多线程应用程序,相应的MFC类库封装了多线程编程的类,用户在开发时可根据应用程序的需要和特点选择相应的工具。为了使大家能全面地了解Windows多线程编程技术,本文将重点介绍Win32API和MFC两种方式下如何编制多线程程序。

多线程编程在Win32方式下和MFC类库支持下的原理是一致的,进程的主线程在任何需要的时候都可以创建新的线程。当线程执行完后,自动终止线程;当进程结束后,所有的线程都终止。所有活动的线程共享进程的资源,因此,在编程时需要考虑在多个线程访问同一资源时产生冲突的问题。当一个线程正在访问某进程对象,而另一个线程要改变该对象,就可能会产生错误的结果,编程时要解决这个冲突。

Win32API下的多线程编程

Win32API是Windows操作系统内核与应用程序之间的界面,它将内核提供的功能进行函数包装,应用程序通过调用相关函数而获得相应的系统功能。为了向应用程序提供多线程功能,Win32API函数集中提供了一些处理多线程程序的函数集。直接用Win32API进行程序设计具有很多优点:基于Win32的应用程序执行代码小,运行效率高,但是它要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源。用Win32API直接编写程序要求程序员对Windows系统内核有一定的了解,会占用程序员很多时间对系统资源进行管理,因而程序员的工作效率降低。

1.用Win32函数创建和终止线程

如果程函数中有任何未被处理的异常,会自动产生一个退出代码,或者线程返回的句柄为o,表示线程没有创建成功,则应用程序将会调用endthread过程 procedureendthread exltciode:int89er ,自动终止线程的运行。互斥锁其实很简单,它只有两种状态:上锁和解锁.在同一时刻只能有一个线程掌握某个互斥的锁,拥有上锁状态的线程能够对共享资源进行操作.若其他线程希望对一个已经上了锁的互斥锁上锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止.操作互斥锁的基本函数与信号量用到的函数相似,主要包括以下这些.。实际上,由于我们在编写程序时就已经知道控件是在哪个线程中创建的.因此也可以在不是创建控件的线程中直接调用控件对象的invoke方法完成对其他线程中的控件的操作.。

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId); 

如果创建成功则返回线程的句柄,否则返回NULL。创建了新的线程后,该线程就开始启动执行了。但如果在dwCreationFlags中使用了CREATE_SUSPENDED特性,那么线程并不马上执行,而是先挂起,等到调用ResumeThread后才开始启动线程,在这个过程中可以调用下面这个函数来设置线程的优先权:

BOOLSetThreadPriority(HANDLEhThread,intnPriority);

当调用线程的函数返回后,线程自动终止。如果需要程的执行过程中终止则可调用函数:

VOIDExitThread(DWORDdwExitCode);

如果程的外面终止线程,则可调用下面的函数:

handlehthread。handlehthread=null。handlehthread=createthread(null,0,runalgorithm,null,0,null)。

虽然该函数立即终止线程的执行,但并不释放线程所占用的资源。 当有若干个线程都要使用某一共享资源时 , 任何时刻最多只允许一个线程去使用 , 其它要使用该资源的线程必须等待 , 直到占用资源者释放该资源 。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。

java线程编程_linux线程编程_多线程编程

如果要终止的线程是进程内的最后一个线程,则线程被终止后相应的进程也应终止。

程体内,如果该线程完全独立,与其他线程没有数据存取等资源操作上的冲突,则可按照通常单线程的方法进行编程。但是,在多线程处理时情况常常不是这样,线程之间经常要同时访问一些资源。由于对共享资源进行访问引起冲突是不可避免的,为了解决这种线程同步问题,Win32API提供了多种同步控制对象来帮助程序员解决共享资源访问冲突。在介绍这些同步对象之前先介绍一下等待函数,因为所有控制对象的访问控制都要用到这个函数。

根据前面两条规则,我们可以知道,如果多个线程同时调用这个函数,当一个线程取得同步锁之后,其他线程就会阻塞在pthread_mutex_lock函数,而当那个取得锁的线程执行到pthread_cond_wait并阻塞之后,在从这个函数返回(条件满足)之前,会释放掉锁,所以其他线程也能一个一个都执行到pthread_cond_wait这里阻塞。c、当其他线程调用pthread_cond_signal或pthread_cond_broadcast时,会唤醒相应条件变量等待的线程,此时被唤醒的线程,可以参与调度了,此时被唤醒的线程继续执行pthread_cond_wait()函数,函数pthread_cond_wait()返回之前,会重新给条件变量对应的互斥量上锁,在这里就是nready.mutex,若该函数成功返回,则当前线程有重新获得了nready.mutex锁,当然nready.mutex也可能被其他线程继续占有,此时线程再次阻塞。中午时翻阅资料发现,在调用弹出框消息时,会调用sendmessage发送消息到消息队列,而sendmessage函数会一直等待消息返回,它不像postmessage函数,而这时主线程中的waitforsingleobject函数又是infinite,所以它一直无限等待,必然导致主线程阻塞,也就导致了消息循环的阻塞,所以这时大家就互相等待,死锁了,导致程序无响应.。

DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);

而函数WaitForMultipleObject可以用来同时监测多个同步对象,该函数的声明为:

dword waitforsingleobject( handlehhandle, dworddwmilliseconds)。调用getlasterror可以得到详细的错误信息 l dword waitformultipleobjects( //等待多个对象 dword ncount, //对象的个数 const handle *lphandles, //对象句柄数组 bool bwaitall, //是否要等到所有的对象都变为信号态 dword dwmilliseconds //等待的毫秒数,如果传入infinite,则无限期等待。 lphandles。

(1)互斥体对象

多线程资源控制,由于线程之间共享进程中的资源多线程编程,所以同一进程中的多个线程的通讯的重心之一是对共享的资源进行控制,例如当多个线程同时使用进程某个资源时,有可能需要采用互斥/同步等手段保证资源被正确操作,在采用互斥/同步手段时候,需要避免产生死锁的情况。互斥量(mutex),信号灯(semaphore),事件(event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。2. 互斥量(mutex),信号灯(semaphore),事件(event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。

首先,建立互斥体对象,得到句柄:

HANDLECreateMutex();

然后,程可能产生冲突的区域前(即访问共享资源之前)调用WaitForSingleObject,将句柄传给函数,请求占用互斥对象:

dwWaitResult=WaitForSingleObject(hMutex,5000L);

共享资源访问结束,释放对互斥体对象的占用:

ReleaseMutex(hMutex);

互斥体对象在同一时刻只能被一个线程占用,当互斥体对象被一个线程占用时,若有另一线程想占用它,则必须等到前一线程释放后才能成功。

多线程编程_linux线程编程_java线程编程

(2)信号对象

suspend count计数初始化为1,创建线程时会检查dwcreateflags参数,只有当参数是create_suspend时才会真正挂起此线程。sta 一个对象只能由一个线程访问(通过对象的接口指针调用其方法),其他线程不得访问这个对象,因此对于这个对象的所有调用都是同步了的,对象的状态(也就是对象的成员变量的值)肯定是正确变化的,不会出现线程访问冲突而导致对象状态错误。为每一个共享资源创建一个lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁:。

首先,创建信号对象:

HANDLECreateSemaphore();

或者打开一个信号对象:

HANDLEOpenSemaphore();

然后,程访问共享资源之前调用WaitForSingleObject。

共享资源访问完成后,应释放对信号对象的占用:

ReleaseSemaphore();

(3)事件对象

事件对象处于两种状态之一:有信号和无信号,线程可以监视处于有信号状态的事件,以便在适当的时候执行对事件的操作。}3.使用事件内核对象(相当好用)利用事件(event)内核对象对线程的通信要复杂些,主要通过对事件对象的监视来实现线程间的通信。-配置nsmachport对象---本地线程间通信,通过传递端口对象变量进行端口间通讯。

如果参数2设置为true,当等待函数接到信号并返回后事件对象不会被自动置于无信号状态,其它等待此事件对象的线程都能够被唤醒。事件对象可以一两种方式创建,一种为自动重置,在其他线程使用 waitforsingleobject等待到事件对象变为有信号后该事件对象自动又变为无信号状态,一种为人工重置在其他线程使用 waitforsingleobject等待到事件对象变为有信号后该事件对象状态不变。 无论自动重置事件对象还是手工重置事件对象,都可以通过setevent函数设置为信号态:bool setevent( handle hevent)。

(4)排斥区对象

并发io问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接 fork 进程,到 worker 进程池/线程池,到现在的异步io、协程。在javascript中,任务分为同步任务和异步任务(异步任务不堵塞当前线程),所有同步任务都在主线程上执行,形成一个执行栈,另外存在一个“任务队列”,如果异步任务有了结果,就在“任务队列”中添加一个事件(对应回调),一旦“执行栈”中的所有同步任务执行完毕,就会读取“任务队列”,取出事件对应的回调,然后进入执行栈执行回调(注:任务队列中对应的是事件,事件可以对应多个回调,回调的执行也依赖事件对象记录的原始参数)。此外,由于同一进程内的多个线程共享进程的地址空间,因此,这些线程之间的同步与通信非常容易实现,甚至无需操作系统的干预。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-106824-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 杨采妮
      杨采妮

      那么要饭的可以几个合娶呀

    热点图片
    拼命载入中...