System中 线程TID48 ntoskrnl.exe!ExQueueWorkItem+0x2f有时突然占用CPU30%到40%
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了System中 线程TID48 ntoskrnl.exe!ExQueueWorkItem+0x2f有时突然占用CPU30%到40%相关的知识,希望对你有一定的参考价值。
有时有有时没有 (开始我以为是不是开机玩久了才有的 后来才发现时有时无 ) 比如前5分钟 频繁的在40%上下 和0之间跳动 这是什么原因啊
System中 ntoskrnl.exe!现在线程变了 开始是TID48的现在便成TID56了 System最高CPU 占用最高达到61%了单个线程已经超过50了 (没有开游戏就360+保险箱还有process Explorer)
[system Idle Process]
进程文件: [system process] or [system process]
进程名称: Windows内存处理系统进程
描 述: Windows页面内存管理进程,拥有0级优先。
介 绍:该进程作为单线程运行在每个处理器上,并在系统不处理其他线程的时候分派处理器的时间。它的cpu占用率越大表示可供分配的CPU资源越多,数字越小则表示CPU资源紧张。
System Idle Process为何物
问:在使用Windows XP的过程中,按“Ctrl Alt Del”键调出任务管理器,在进程中我发现一个名为“System Idle Process”的进程,它往往占用了大部分CPU资源,经常是80%以上,请问为什么它占用了那么多资源?
答:你误解了“System Idle Process”进程的意思了,这里的80%并不是你所想的占用CPU的资源,恰恰相反的是这里的80%以上是CPU资源空闲了出来的。这里的数字越大表示CPU可用资源越多,数字越小则表示CPU资源越紧张。该进程是系统必须的,不能禁止哦
如何从父线程中提取pthread的taskid(tid)?
【中文标题】如何从父线程中提取pthread的taskid(tid)?【英文标题】:How to extract taskid(tid) of a pthread from the parent thread? 【发布时间】:2019-06-13 20:23:39 【问题描述】:我正在使用 std::thread 来启动线程。另外,我需要/proc/[pid]/tasks/[tid]
提供的工作线程的统计信息。我需要 tid 才能监控线程统计信息。我想知道是否有办法从父线程中提取tid
。我知道来自工作人员的系统调用 gettid() 返回其 ID,但我想要来自主服务器而不是从服务器的 threadId。有没有办法从 std::thread.get_tid() 的 thread_id gor 中提取 tid
?
我相信可能有更好的方法可以做到这一点,请提出建议:)
更新:How can you get the Linux thread Id of a std::thread() 这提供了一些关于从工作人员那里获取 tid 的信息,增加了线程启动的开销。例如,std::thread t = std::thread(&wrapper);
t.get_id()
可以从启动器线程中调用。我正在/正在寻找是否可以从主/启动器线程以安全的方式执行相同的操作。
【问题讨论】:
线程与后继前继等进程没有关系。 可能重复:How can you get the Linux thread Id of a std::thread() How can you get the Linux thread Id of a std::thread()的可能重复 【参考方案1】:所有线程都有一个唯一的 id:std::thread::id this_id = std::this_thread::get_id();
您可以在程序启动时将它存储在一个变量中,并且可以从其他线程访问它。
我明白你所说的父线程是什么意思,但是即使一个线程生了另一个线程,它们也是兄弟姐妹。
如果您希望 master 线程能够获得每个 worker 线程的 /proc
路径,您可以将工作线程对象包装在一个类中,当它启动实际线程时,会创建一个 master 稍后可以获取的路径属性。
一个例子:
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
// A base class for thread object wrappers
class abstract_thread
public:
abstract_thread()
abstract_thread(const abstract_thread&) = delete;
abstract_thread(abstract_thread&& rhs) :
m_th(std::move(rhs.m_th)), m_terminated(rhs.m_terminated), m_cv, m_mtx
abstract_thread& operator=(const abstract_thread&) = delete;
abstract_thread& operator=(abstract_thread&& rhs)
terminate();
join();
m_th = std::move(rhs.m_th);
m_terminated = rhs.m_terminated;
return *this;
virtual ~abstract_thread()
// make sure we don't destroy a running thread object
terminate();
join();
virtual void start()
if(joinable())
throw std::runtime_error("thread already running");
else
std::unique_lock<std::mutex> lock(m_mtx);
m_terminated = true;
// start thread and wait for it to signal that setup has been done
m_th = std::thread(&abstract_thread::proxy, this);
m_cv.wait(lock, [this] return m_terminated == false; );
inline bool joinable() const return m_th.joinable();
inline void join()
if(joinable())
m_th.join();
inline void terminate() m_terminated = true;
inline bool terminated() const return m_terminated;
protected:
// override if thread specific setup needs to be done before start() returns
virtual void setup_in_thread()
// must be overridden in derived classes
virtual void execute() = 0;
private:
std::thread m_th;
bool m_terminated;
std::condition_variable m_cv;
std::mutex m_mtx;
void proxy()
std::unique_lock<std::mutex> lock(m_mtx);
setup_in_thread(); // call setup function
m_terminated = false;
m_cv.notify_one();
execute(); // run thread code
;
// an abstract thread wrapper capable of returning its /proc path
class proc_path_thread : public abstract_thread
public:
// function to call from master to get the path
const std::string& get_proc_path() const return m_proc_path;
protected:
void setup_in_thread() override
m_proc_path =
std::move(std::string("/proc/")) + std::to_string(syscall(SYS_gettid));
private:
std::string m_proc_path;
;
// two different thread wrapper classes. Just inherit proc_path_thread and implement
// "execute()". Loop until terminated() is true (or you're done with the work)
class AutoStartThread : public proc_path_thread
public:
AutoStartThread() start();
private:
void execute() override
while(!terminated())
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << std::this_thread::get_id() << " AutoStartThread running\n";
;
class ManualStartThread : public proc_path_thread
void execute() override
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << std::this_thread::get_id() << " ManualStartThread running\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
;
int main()
AutoStartThread a;
std::cout << a.get_proc_path() << "\t// AutoStartThread, will have path\n";
ManualStartThread b;
std::cout << b.get_proc_path()
<< "\t// ManualStartThread not started, no path\n";
b.start();
std::cout << b.get_proc_path()
<< "\t// ManualStartThread will now have a path\n";
b.join();
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
// terminate() + join() is called automatically when abstract_thread descendants
// goes out of scope:
//
// a.terminate();
// a.join();
可能的输出:
/proc/38207 // AutoStartThread, will have path
// ManualStartThread not started, no path
/proc/38208 // ManualStartThread will now have a path
139642064209664 ManualStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
【讨论】:
这实际上与我想要的相反,我不喜欢从工作人员那里使用 gettid() (我觉得它膨胀性能,因为需要保护或继续检查全局用于填充 tid 的变量)。例如std::thread t = std::thread(&wrapper);
;来自主上下文的t.get_id()
将给出实际的线程ID。你怎么看?
好的,我明白了。当然,您可以反过来做,以便 master 查询 worker 的路径。只需为每个线程添加一个condition_variable
,该线程向主发出信号,表明本机pid_t
已放入map
。也许最好用一些同步围绕线程对象创建一个类,这样你就可以安全地执行th.get_path()
。
@ShashankHegde 制作了一个新版本。希望这次我没听错:)【参考方案2】:
您可以通过一个函数启动线程,该函数的第一个任务是发送它的 id 消息,例如,通常使用互斥锁和 condvars:
#include <stdio.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <unistd.h>
struct tid_msg
pthread_mutex_t mx;
pthread_cond_t cond;
pid_t tid;
;
void *thr(void*A)
struct tid_msg *msg = A;
pid_t tid = syscall(SYS_gettid);
pthread_mutex_lock(&msg->mx);
msg->tid = tid;
pthread_mutex_unlock(&msg->mx);
pthread_cond_signal(&msg->cond);
printf("my tid=%lu\n", (long unsigned)tid);
return 0;
int main()
struct tid_msg msg = PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, -1 ;
pthread_t ptid;
pthread_create(&ptid,0,thr,&msg);
pthread_mutex_lock(&msg.mx);
while(-1==msg.tid) pthread_cond_wait(&msg.cond,&msg.mx);
pthread_mutex_unlock(&msg.mx);
printf("their tid=%lu\n", (long unsigned)msg.tid);
pthread_join(ptid,0);
或者简单地通过一个原子变量(在这里宽松的内存排序应该没问题, 但你可以安全地使用它并使用顺序一致的默认值):
#include <stdio.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdatomic.h>
void *thr(void*A)
_Atomic pid_t *tidp = A;
pid_t tid;
tid = syscall(SYS_gettid);
atomic_store_explicit(tidp, tid, memory_order_relaxed);
printf("my tid=%lu\n", (long unsigned)tid);
return 0;
int main()
_Atomic pid_t tid=-1;
pthread_t ptid;
pthread_create(&ptid,0,thr,&tid);
while(-1==atomic_load_explicit(&tid,memory_order_relaxed)) ;
printf("their tid=%lu\n", (long unsigned)tid);
pthread_join(ptid,0);
【讨论】:
这两个选项基本上都在等待 CV 旋转。我想知道哪个选项对性能更好?尤其是当有很多线程要管理时?非常感谢:) @ShashankHegde 我敢打赌旋转版本(原子)。线程创建时间不应长到保证父线程进入睡眠状态。以上是关于System中 线程TID48 ntoskrnl.exe!ExQueueWorkItem+0x2f有时突然占用CPU30%到40%的主要内容,如果未能解决你的问题,请参考以下文章
win7 system进程 ntoskrnl.exe占用CPU很高
安装了双系统后(windows server 2003),启动xp时,显示文件<windows root>system32\ntoskrnl.exe缺失。