相关文章推荐
低调的饭盒  ·  Microsoft Entra ...·  1 周前    · 
乖乖的夕阳  ·  特殊的数据类型: ...·  1 年前    · 
直爽的跑步机  ·  x86 intrinsics list | ...·  1 年前    · 

实际上你不可能事先知道什么事情要等待多久,比如一个高优先级线程抢占执行的话,这个时间将变得不可预测。

要注意的是,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助手: 非常感谢您分享这篇有用的博客!对于像我这样使用AMD处理器的Android Studio用户来说,这些解决方法非常有用。我认为,下一篇博客可以探讨如何在Android Studio中使用NDK开发,这对于想要深入学习Android开发的读者来说非常有价值。相信您会有更多的读者受益。 为了方便博主创作,提高生产力,CSDN上线了AI写作助手功能,就在创作编辑器右侧哦~(https://mp.csdn.net/edit?utm_source=blog_comment_recall )诚邀您来加入测评,到此(https://activity.csdn.net/creatActivity?id=10450&utm_source=blog_comment_recall)发布测评文章即可获得「话题勋章」,同时还有机会拿定制奖牌。 C++拷贝构造函数详解 野指针问题吧,怕传的指针压根没有内容会出问题 C++拷贝构造函数详解 团子要当程序媛: 引用「if(p != NULL) { delete p; 」 不太明白为何要判断if(p!=NULL) C++拷贝构造函数详解 团子要当程序媛: 引用「p = new int; // 为新对象重新动态分配空间 *p = *(r.p)」 能否合并成"p=new int(100);",会出问题吗?好像p=new int;*p=*(r.p);通用性更强 详解C语言中volatile关键字 YPSXYY: 二、volatile 的含义,这一节最后举的jiffies的例子我没看懂,mov jiffies,%eax不是将寄存器的值存到jiffies里面吗?然后寄存器++,然后将jiffies的值再搬回寄存器,三条命令下来jiffies和寄存器的值都没变吧?