美文网首页
线程调度

线程调度

作者: FallMR | 来源:发表于2017-02-20 22:04 被阅读0次

线程内核对象中有个叫做挂起计数的东西
每次调用CreateProcess或者CreateThread时
这个东西就会在线程内核对象创建后初始化为1
然后在线程初始化完成前 就不会被调度了
然后在初始化之后 CreateProcess和CreateThread会检查有没有CREATE_SUSPENDED标志传入
有的话函数就会将这个线程挂起 没有则挂起计数会变0
然后线程就可以被调度了
对于处于挂起状态的线程 我们可以在线程执行任何代码前改变它的环境(如优先级)


然后就是把线程变成可调度的的方法:
调用ResumeThread函数 传入线程句柄
成功将返回线程的前一个挂起计数 失败则返回0xFFFFFFFF
一个线程可以多次挂起 挂起多少次就要Resume多少次才能调度
DWORD ResumeThread(HANDLE hThread);

另外还可以通过SuspendThread函数来挂起线程
DWORD SuspendThread(HANDLE hThread);
这个函数的返回值和ResumeThread相同
(一个线程最多可以挂起MAXIMUM_SUSPEND_COUNT次[WinNT.h中定义为127])


进程的挂起和恢复(并不存在的概念)

这是一个挂起进程中所有线程的问题
虽然没有现成的比较好的函数
但是我们可以自己写一个

VOID SuspendProcess(DWORD dwProcessID, BOOL fSuspend) {
    HANDLE hThreadSnapShot = INVALID_HANDLE_VALUE;
    THREADENTRY32 te32 = {sizeof(te32)};
    hThreadSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
    if (hThreadSnapShot != INVALID_HANDLE_VALUE) {
        Thread32First(hThreadSnapShot, &te32);
        do {
            if (te32.th32OwnerProcessID == dwProcessID) {
                HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID);
                if (hThread != NULL) {
                    if (fSuspend) {
                        SuspendThread(hThread);
                    }else{
                        ResumeThread(hThread);
                    }
                }
                CloseHandle(hThread);
            }
        }while (Thread32Next(hThreadSnapShot, &te32));
        CloseHandle(hThreadSnapShot);
    }
}  

线程还可以干一件叫做睡眠的事情 大概就是一段时间内不接受调度的(傲娇)行为
VOID Sleep(DWORD dwMilliseconds);
具体作用就是会停止dwMilliseconds ms的时间
如果传入0的话 其实就是强制系统去调用另外一个线程(然后这个线程还可以调度 嗯标准傲娇)


切换到另一个线程的方法:
使用函数SwitchToThread()
这是一个并没有参数的函数
所以有必要解释一下调用时会发生什么:
首先系统会查看是否存在急需CPU时间的饥饿进程

  • 没有:立即返回
  • 有:调度这个线程

那么这个函数和Sleep(0)的作用的区别在哪儿呢= =
答案是 Sleep(0)之后系统会运行优先级最高的线程
SwitchToThread允许运行优先级比自己低的线程


有时候需要计算线程运行的时间
一般的做法(误):

ULONGLONG qwStartTime = GetTickCount64();
...(somethings needed to do)
ULONGLONG qwElapsedTime = GetTickCount64() - qwStartTime;  

这样做表面看并没有问题 但问题是windows是个抢占式的系统
所以。。就会坑
于是你需要使用

BOOL GetThreadTimes (
  HANDLE hThread,
  LPFILETIME lpCreationTime,
  LPFILETIME lpExitTime,
  LPFILETIME lpKernelTime,
  LPFILETIME lpUserTime
);

相关文章

  • java虚拟机读书笔记之线程调度

    java线程调度 线程调度主要有两种方式,协同式线程调度和抢占式线程调度。1、协同式: 线程的执行时间由线程本身...

  • [Java]线程和锁

    0x00 线程调度 线程调度指的是系统为线程分配CPU使用权。分为两种: 协同式线程调度线程想用CPU多久就用多久...

  • CPU调度

    CPU调度 基本概念 CPU调度在讨论普通调度概念时使用进程调度,特别指定为线程概念时使用线程调度 CPU-I/O...

  • 2018-04-03 线程基础

    线程调度 是指系统分配CPU使用权限的方式,分为协同式线程调度和抢占式线程调度 进程、线程概念 进程是应用程序的一...

  • 线程优先级和守护线程

    线程优先级: Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定调度哪个...

  • 并发--线程和锁

    线程调度 协同式调度 1.一个线程执行完毕之后再通知其他线程执行 抢占式调度(JAVA使用的是这种方式) 1.os...

  • 2.1 Java线程调度

    线程调度是指系统为线程分配处理器使用权的过程,主要调度方式有两种,分别是协同式线程调度(CooperativeTh...

  • 网络编程(三)

    Volley用法完全解析 从上图可以看到Volley分为三个线程,分别是主线程、缓存调度线程、和网络调度线程,首先...

  • EffectiveJava第十章第七节

    不要依赖于线程调度器 当有多个线程可以运行时,由线程调度器(thread scheduler)决定哪些线程将会运行...

  • 08-JAVA线程[1]

    线程调度分为两种:1)分时调度:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。2) 抢占调度:...

网友评论

      本文标题:线程调度

      本文链接:https://www.haomeiwen.com/subject/gwtywttx.html