实际上你不可能事先知道什么事情要等待多久,比如一个高优先级线程抢占执行的话,这个时间将变得不可预测。
要注意的是,Sleep( ),会放弃系统分配的剩余的时间片,这样 OS 就能更好的服务其他的进程和线程了。
2. busy loop
for (;;)
GetExitCodeThread(hThrd1, &exitCode1);
if ( exitCode1 == STILL_ACTIVE )
puts("Thread 1 is still running!");
}
忙等,是很浪费CPU时间的!因为 for( ) 在一直工作。
二. 等待线程结束
//等待一个线程结束
DWORD WaitForSingleObject(
HANDLE hHandle, // handle to object
DWORD dwMilliseconds // 最长的等待时间,INFINITE 表示无穷等待
// 返回值:
// WAIT_FAILED, 表示函数失败
// WAIT_OBJECT_0, 表示等待的核心对象变成激发状态
// WAIT_TIMEOUT, 表示核心对象在变成激发状态之前,时间终了了
//等待多个线程结束
DWORD WaitForMultipleObjects(
DWORD nCount, // handles 数组元素个数
CONST HANDLE *lpHandles, // handles 数组
BOOL bWaitAll, // TRUE 表示所有的handles都必须激发,此函数才得以返回
DWORD dwMilliseconds // 终了时间
// 返回值:
// WAIT_TIMEOUT, 时间终了
// WAIT_FAILED, 表示函数失败
// bWaitAA == TRUE, 返回值是 WAIT_OBJECT_0
// bWaitAA == FASLE, 返回值减去 WAIT_OBJECT_0,就表示数组中的哪一个 handle 被激发了
// WAIT_TIMEOUT, 表示核心对象在变成激发状态之前,时间终了了
WaitForXXXObject( ),相当于一个新版的 sleep( ),它能够在某个线程结束时被调用。
WaitForXXXObject( ),像 sleep( )一样,只会占用很少的CPU,不会出现忙等现象,所以效率会高很多。
WaitForXXXObject( ),到底在等什么?
其实它等待的是一些对象被激发
。
三. 被激发对象
可被 WaitForXXXObject( )使用的核心对象有两种状态:激发与未激发,WaitForXXXObject( ) 在目标变成激发状态时才返回。
Thread 当线程结束时,线程对象即被激发
Process 当进程结束时,进程对象即被激发
Event 直接受控于 SetEvent(),PulseEvent(),ResetEvent()三个函数
Mutex 如果 mutex 没有被任何线程拥有,它就处于激发状态
Semaphore 当计数器内容大于0时,semaphore处于激发状态
当出现以上对象动作时,线程对象就会被激发,此时 WaitForXXXObject( ) 就能返回。
四. 示例代码
最多用三个线程来完成六项工作
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
DWORD WINAPI ThreadFunc(LPVOID);
#define THREAD_POOL_SIZE 3 //线程池大小为3
#define MAX_THREAD_INDEX THREAD_POOL_SIZE-1
#define NUM_TASKS 6 //共有6个任务
int main()
HANDLE hThrds[THREAD_POOL_SIZE];
int slot = 0;
DWORD threadId;
int i;
DWORD rc;
for (i=1; i<=NUM_TASKS; i++)
/* 当用完线程池里所有的线程时,要等待其它线程结束 */
if (i > THREAD_POOL_SIZE)
/* 等待一个线程结束 */
rc = WaitForMultipleObjects(
THREAD_POOL_SIZE,
hThrds,
FALSE,
INFINITE );
slot = rc - WAIT_OBJECT_0;
printf("Slot %d terminated\n", slot );
CloseHandle(hThrds[slot]);
/* 创建 6 个线程 */
hThrds[slot] = CreateThread(NULL,
ThreadFunc,
(LPVOID)slot,
&threadId );
printf("Launched thread #%d (slot %d)\n", i, slot);
slot++;
/* 等待所有的线程结束 */
rc = WaitForMultipleObjects(
THREAD_POOL_SIZE,
hThrds,
TRUE,
INFINITE );
for (slot=0; slot<THREAD_POOL_SIZE; slot++)
CloseHandle(hThrds[slot]);
printf("All slots terminated\n");
return EXIT_SUCCESS;
* This function just calls Sleep for
* a random amount of time, thereby
* simulating some task that takes time.
* The param "n" is the index into
* the handle array, kept for informational
* purposes.
DWORD WINAPI ThreadFunc(LPVOID n)
srand( GetTickCount() );
Sleep((rand()%10)*800+500);
printf("Slot %d idle\n", n);
return ((DWORD)n);
代码是《Win32多线程程序设计》上的,很经典。
一. 一般等待1. sleep()在操作系统中止此线程动作,直到渡过某个时间之后才恢复。VOID Sleep( DWORD dwMilliseconds // sleep time);实际上你不可能事先知道什么事情要等待多久,比如一个高优先级线程抢占执行的话,这个时间将变得不可预测。要注意的是,Sleep( ),会放弃系统分配的剩余的时间片,这样 OS 就能更好的服务
文章目录Thread的几个重要方法线程通知与等待wait()/notify()/notifyAll()wait()函数获取监视器锁synchronized同步代码块共享变量方法,方法使用synchronized修饰虚假唤醒举例:消费者&生产者唤醒函数notify()函数notifyAll()函数等待线程执行终止join睡眠sleep让出CPU执行权yield()
Thread的几个重要方法
线程通知与等待wait()/notify()/notifyAll()
Object类是所有类的父类,鉴于继承机
开发过程中经常遇到需要等待某线程结束的情况,目前碰到两种方法,总结下。以后有增加再更新。
1)CountDownLatch
CountDownLatch是一个同步辅助类,可以用来等待一个或者几个线程结束。
主要的方法是countDown和await
import java.util.concurrent.CountDownLatch;
clusterEnd = new CountDown
线程状态:辅助
线程进行调度,java中
线程的状态是通过一个enum来表示的。
NEW:表示
Thread对象有了,PCB没有。
RUNNABLE:准备就绪,正在cpu执行或者已经准备好上cpu执行。
BLOCKED:
等待锁,阻塞状态,暂时不上cpu。
WAITING:
在Winform中,多线程等待可以通过以下几种方式实现:
1. 使用Thread.Join()方法。该方法会阻塞当前线程,直到等待的线程执行完毕。例如,在主线程中创建了多个子线程,可以使用Join()方法让主线程等待每个子线程的执行结果,然后再继续执行。
2. 使用ManualResetEvent类。该类提供了两个方法WaitOne()和Set(),前者会阻塞当前线程,直到调用Set()方法来通知线程继续执行。可以在子线程中使用WaitOne()方法,然后在主线程中调用Set()方法,来实现线程的同步。这种方式可以比较精细的控制等待时间和通知方式。
3. 使用Task.WaitAll()方法。该方法可以让当前线程等待所有Task任务都执行完毕后再继续执行。在Winform中,可以使用Task.Factory.StartNew()方法来创建异步任务,然后使用WaitAll()方法来等待它们的执行结果。
需要注意的是,在使用多线程等待时,要避免死锁的情况。例如,在两个线程中,如果各自都使用WaitOne()方法来等待对方的通知,那么两个线程就会一直等待下去,导致死锁。因此,在设计多线程等待时,要仔细考虑各个线程的等待和通知方式,以避免死锁等问题。
CSDN-Ada助手:
C++拷贝构造函数详解
C++拷贝构造函数详解
团子要当程序媛:
C++拷贝构造函数详解
团子要当程序媛:
详解C语言中volatile关键字
YPSXYY: