VISUAL C++使用Windows线程池(Vista的CreateThreadpoolWork,如果可用,QueueUserWorkItem如果不)调用时std::async用std::launch::async.
池中的线程数是有限的.如果创建多个运行很长时间而没有休眠的任务(包括执行I/O),则队列中即将发生的任务将无法工作.
标准(我使用N4140)表示,借助std::async与std::launch::async
...调用
INVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)(20.9.2,30.3.1.2),好像在一个新的执行线程中,由一个线程对象表示,并调用在DECAY_COPY()被调用的线程中进行求值async.
(§30.6.8p3,强调我的.)
std::thread的构造函数创建了一个新线程等.
关于一般的线程,它说(§1.10p3):
实现应确保所有未阻塞的线程最终取得进展.[ 注意:标准库函数可能会静默阻塞I/O或锁定.执行环境中的因素(包括外部强加的线程优先级)可能会阻止实现对前进进度做出某些保证.- 结束说明 ]
如果我创建了一堆OS线程或std::threads,都执行一些非常长(或许是无限)的任务,它们都将被安排(至少在Windows上;不会弄乱优先级,亲和力等).如果我们将相同的任务安排到Windows线程池(或使用std::async(std::launch::async, ...)哪个任务),则在先前的任务完成之前,后续计划的任务将不会运行.
严格来说,这是合法的吗?什么"最终"意味着什么?
问题是如果首先安排的任务事实上是无限的,那么剩下的任务就不会运行.所以其他线程(不是OS线程,但根据as-if规则的"C++ - 线程")将无法取得进展.
有人可能会争辩说,如果代码具有无限循环,则行为是不确定的,因此它是合法的.
但我认为,我们不需要标准所说的有问题的无限循环导致UB实现这一点.访问易失性对象,执行原子操作和同步操作都是"禁用"循环终止假设的副作用.
(我有一堆执行以下lambda的异步调用
auto lambda = [&] {
while (m.try_lock() == false) {
for (size_t i = 0; i < (2 << 24); i++) {
vi++;
}
vi = 0;
}
};
Run Code Online (Sandbox Code Playgroud)
并且只有在用户输入时才会释放锁定.但是还有其他有效的合法无限循环.)
如果我安排了几个这样的任务,我在他们之后安排的任务就无法运行. …
某些Windows API返回主令牌,有些返回模拟令牌.某些API需要主令牌,而其他API则需要模拟令牌.
例如,LogonUser通常返回主令牌,除非LOGON32_LOGON_NETWORK用作登录类型(dwLogonType)时:
在大多数情况下,返回的句柄是您可以在调用CreateProcessAsUser函数时使用的主令牌.但是,如果指定LOGON32_LOGON_NETWORK标志,则LogonUser将返回您无法在CreateProcessAsUser中使用的模拟标记,除非您调用DuplicateTokenEx将其转换为主标记.
SetThreadToken需要一个模拟令牌,而ImpersonateLoggedOnUser这似乎做同样的事情需要一个.
CreateProcessAsUser并且CreateProcessWithTokenW两者都需要一个主令牌,并注意可以通过调用从模拟令牌中获取主令牌DuplicateTokenEx,但令牌类型是什么意思?
词汇表说明如下:
访问令牌包含登录会话的安全信息.系统在用户登录时创建访问令牌,并且代表用户执行的每个进程都具有令牌的副本.令牌标识用户,用户的组和用户的权限.系统使用令牌来控制对安全对象的访问,并控制用户在本地计算机上执行各种系统相关操作的能力.有两种访问令牌,主要和模拟.
通常仅由Windows内核创建的访问令牌.可以将其分配给进程以表示该进程的默认安全信息.
已创建的访问令牌,用于捕获客户端进程的安全信息,允许服务器在安全操作中"模拟"客户端进程.
但这并不完全有用.似乎有人想要使用像"内核"这样的大男孩字样,但这只会引发更多问题,例如除了被分配到进程之外还可以使用主要令牌以及除了内核之外的其他人可以创建访问权限令牌?
(他们的意思是微软的意思,内核只是内核模式运行的一部分,还有执行等等,或者他们是否意味着用户模式代码也可以创建令牌?无论如何,即使用户 - 模式代码可以创建令牌,它必须通过系统调用来完成,就像任何对象管理器对象一样,所以无论如何,令牌实际上都是以内核模式创建的.)
无论如何,这并没有回答基本问题:令牌类型之间有什么区别?不是它们可能被用于什么或通常如何创建它们.
我有一个问题导致Firefox在启动过程中表现得很奇怪.
(具体来说,它显示" Firefox似乎很慢......到...开始 "的消息,即使我没有安装任何新的扩展或类似的东西.)
显示该消息的函数_showSlowStartupNotification在browser/components/nsBrowserGlue.js其中被调用,该函数_trackSlowStartup依次被调用_onFirstWindowLoaded.
我想调试一下.我怎样才能做到这一点?
我可以使用WinDbg和Mozilla的符号服务器轻松调试Firefox二进制文件.但这不是我想要的.我想调试XUL,而不是C++.
如果启用浏览器工具箱,我可以调试XUL ,但只能在启动后调试.即使我设置devtools.debugger.prompt-connection为false并运行firefox.exe -jsdebugger以立即打开浏览器工具箱,我只有在启动代码已经执行后才能访问它.在有趣的函数上设置断点并没有帮助,因为它们不是持久的; 重新启动Firefox不会导致内部XUL调试器中断它们.
那么,有什么建议吗?有没有办法从早期开始调试Firefox的XUL?