我看到PHP的不同二进制文件,如非线程或线程安全?这是什么意思?这些套餐有什么区别?
我已经实现了PARLANSE,这是MS Windows下的一种语言,它使用cactus栈来实现并行程序.堆栈块被分配在每个功能的基础上,并只处理局部变量的大小合适,表达温度推/持久性有机污染物,并调用库(包括存储库程序工作在堆栈空间).在实践中,这样的堆栈帧可以小到32个字节,并且通常是这样.
这一切都很有效,除非代码做了一些愚蠢的事情并导致硬件陷阱......此时Windows似乎坚持在堆栈上推送整个x86机器上下文.如果包含FP/MMX /等,则大约500多个字节.寄存器,它做的.当然,32字节堆栈上的500字节推送会破坏它不应该的东西.(硬件在陷阱上推了几个字,但不是整个上下文).
[编辑2012年11月27日:请参阅此测量的细节上堆叠的荒谬量Windows实际上推动 ]
我可以让Windows在其他地方存储异常上下文块(例如,到特定于线程的位置)吗?然后软件可以对线程进行异常命中并处理它而不会溢出我的小堆栈帧.
我不认为这是可能的,但我想我会问更多的观众.是否有OS标准调用/接口可能导致这种情况发生?
如果我可以让MS让我的进程可选地定义一个上下文存储位置"contextp",那么在操作系统中这样做是微不足道的,这个位置被初始化以默认启用当前的遗留行为.然后替换中断/陷阱向量代码:
hardwareint: push context
mov contextp, esp
Run Code Online (Sandbox Code Playgroud)
...... ......
hardwareint: mov <somereg> contextp
test <somereg>
jnz $2
push context
mov contextp, esp
jmp $1
$2: store context @ somereg
$1: equ *
Run Code Online (Sandbox Code Playgroud)
保存somereg等所需的明显变化
[我现在做的是:检查每个函数的生成代码.如果它有可能生成陷阱(例如,除以零),或者我们正在调试(可能是坏指针deref等),请为FP上下文添加足够的空间到堆栈帧.堆栈帧现在最终大小约为500-1000字节,程序无法递归到目前为止,这对我们正在编写的应用程序来说有时是一个真正的问题.所以我们有一个可行的解决方案,但它使调试变得复杂]
编辑8月25日:我已经成功地将这个故事告诉了一位微软的内部工程师,他有权明确地找出MS中谁可能真正关心的人.解决方案可能有微弱的希望.
编辑9月14日:MS Kernal Group Architect听过这个故事并且很有同情心.他说MS将考虑一个解决方案(如提议的解决方案),但不太可能在服务包中.可能必须等待下一版本的Windows.(叹气......我可能会变老......)
编辑:2010年9月13日(1年后).微软没有采取任何行动.我最近的噩梦:在Windows X64上运行一个32位进程的陷阱,在中断处理程序伪造推动32位上下文之前,将整个X64上下文推送到堆栈上?那甚至更大(两倍宽的整数寄存器,两倍的SSE寄存器(?))?
编辑:2012年2月25日:( 1.5年过去了......)微软没有反应.我猜他们只是不关心我的并行性.我认为这对社区不利; MS在正常情况下使用的"大堆栈模型"限制了通过食用大量VM可以在任何一个瞬间生存的并行计算量.PARLANSE模型将允许一个应用程序在运行/等待的各种状态下具有一百万个活"谷粒"; 这在我们的一些应用程序中确实发生,其中"并行"处理了1亿个节点图.PARLANSE方案可以使用大约1Gb的RAM来实现这一点,这是非常易于管理的.如果您尝试使用MS 1Mb"大堆栈",那么您只需要10 ^ 12个字节的VM用于堆栈空间,我非常确定Windows不会让您管理一百万个线程.
编辑:2014年4月29日:( 4年过去了). 我想MS只是不读SO. 我已经在PARLANSE上完成了足够的工程设计,因此我们只需要在调试期间支付大型堆栈帧的价格,或者当FP操作正在进行时,所以我们设法找到非常实用的方法来实现这一点.MS继续令人失望; 各种版本的Windows推送到堆栈上的东西量似乎变化很大,而且非常严重地超出了对硬件环境的需求.有一些暗示,这种可变性是由于非MS产品坚持(例如防病毒)在异常处理链中嗤之以鼻; 为什么他们不能从我的地址空间之外做到这一点?任何,我们通过简单地为FP /调试陷阱添加一个大的slop因子,并等待超过该数量的字段中不可避免的MS系统来处理所有这些.
stack-overflow assembly exception cpu-registers threadcontext
目的是ExecutionContext.SuppressFlow();
什么?在下面的代码中究竟被抑制了什么?
我有这个测试代码......
protected void btnSubmit_Click(object sender, EventArgs e)
{
Thread[] th = new Thread[100];
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-GB");
AsyncFlowControl cntrl = ExecutionContext.SuppressFlow();
for (int i = 0; i < th.Length; i++)
{
th[i] = new Thread(new ParameterizedThreadStart(ThreadMethod));
th[i].Name = "Thread #" + (i+1).ToString();
th[i].Start((i+1).ToString());
}
ExecutionContext.RestoreFlow();
foreach (Thread t in th)
{
t.Join();
}
Response.Write(response);
}
String response = null;
Random rnd = new Random(1000);
private void ThreadMethod(object param)
{
if (param != null)
{
string temp …
Run Code Online (Sandbox Code Playgroud) 我有一个WCF服务,它记录每次调用数据库.稍后,如果发生异常,它也会记录到单独的数据库中.
我想要一种方法将这两个日志绑定在一起,这样我们就可以看到可能导致异常的原因.要做到这一点,我想要一些我可以为每次通话获得的唯一ID.
由于整个事情在单个线程上执行,我可以例如将线程名称设置为GUID,例如.System.Threading.Thread.CurrentThread.Name = Guid.NewGuid().ToString();
但这有点笨拙.
在网上搜索,我发现System.Threading.Thread.CurrentContext.SetProperty()
但我想知道那个背景到底是什么.它是否设计用于存储线程持续时间的属性?每个线程都是唯一的吗?
如果我同时有5个WCF呼叫,我不希望在上下文中发生什么冲突,如果它不是"每次呼叫"可以这么说.
有人可以澄清吗?
我正在尝试记录来自 http 客户端的原始请求/响应。我正在按照这些日志记录说明中的 log4j2 配置进行操作。
HttpAsync 客户端依赖项:- httpasyncclient(版本 4.1.1)
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingRandomAccessFile name="app-log" fileName="${log.path}/app.log"
filePattern="${log.path}/app-%d{yyyy-MM-dd}.gz">
<PatternLayout>
<pattern>[%-5level] [%X{uuid}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<AsyncLogger name="org.apache.http.impl.conn.Wire" level="debug">
<AppenderRef ref="app-log"/>
</AsyncLogger>
<AsyncRoot level="debug" includeLocation="true">
<AppenderRef ref="app-log"/>
</AsyncRoot>
</Loggers>
</Configuration>
Run Code Online (Sandbox Code Playgroud)
它打印正常,但线程上下文没有传递到线路记录器上。
例子 :-
// with uuid, output of logger.debug(ThreadContext.getImmutableContext().toString());
[DEBUG] [c48b97f7-0094-44af-82af-3d6b43d76014] 2016-11-14 17:06:03.408 [http-bio-8080-exec-1] OutboundRequestHandler - {uuid=c48b97f7-0094-44af-82af-3d6b43d76014}
// without uuid
[DEBUG] [] 2016-11-14 17:06:03.440 [I/O dispatcher …
Run Code Online (Sandbox Code Playgroud) 我在 Windows 7 64 位机器上工作(我有管理员权限)。
我正在使用 Python 2.7(64 位)和 PyDev ctypes for Eclipse 尝试读取与特定 PID 关联的所有线程中寄存器的值(尝试了在 64 位和 32 位模式下运行的进程的 PID),但是当我这样做,寄存器的值都被清零了。当我使用时Wow64GetThreadContext
,调用失败并GetLastError
返回 0x00000057(根据 MSDN,'无效参数')
我成功地附加到进程,枚举线程(通过CreateToolhelp32Snapshot
),使用适当的 PID 找到进程拥有的线程,并尝试获取线程上下文。这是我打开线程并获取线程上下文的代码:
打开一个线程:
def open_thread(self, thread_id):
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
Run Code Online (Sandbox Code Playgroud)
获取上下文:
def get_thread_context(self, thread_id = None, h_thread = None):
context = CONTEXT()
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
#alternatively, for 64
context64 = WOW64_CONTEXT()
context64.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
#Obtain a handle to the thread
if h_thread is None:
self.h_thread …
Run Code Online (Sandbox Code Playgroud) 这不是一个重要的问题,但我想知道为什么Thread类公开一个属性来获取当前的Context(Thread.CurrentContext)和一个获取当前AppDomain(Thread.GetDomain())的方法.
知道Process> AppDomain> Context> Thread的层次结构,我的假设是在当前时间点知道线程的上下文,并且需要根据当前上下文搜索域.
但我想听听更明智的答案.谢谢!
我一直在研究一个使用log4j2的项目,在这个项目中我使用ThreadContext.现在我回到使用log4j(1),它不提供ThreadContext.ThreadContext有什么好的选择吗?谷歌搜索还没有给我任何好的想法,所以我希望这里有人可能有一些意见.
我正在尝试记录 Java 应用程序的事件,以根据设置为 ThreadContext 的键来分隔日志文件。但是即使在系统属性中将“log4j2.isThreadContextMapInheritable”设置为“true”之后,我的密钥也没有到达子线程(在 MouseEvent 上创建)。有人请帮我解决这个问题。
我的主要方法:
public class Application {
static {
System.setProperty("log4j2.isThreadContextMapInheritable","true");
}
private final static Logger LOGGER = LogManager.getLogger(Application.class);
public static void main(String[] args) throws Exception
{
ThreadContext.put("cfg","RLS");
LOGGER.info("New window opening!!!"+ThreadContext.get("cfg"));
newWindow();
}
private static void newWindow() throws Exception {
ButtonFrame buttonFrame = new ButtonFrame("Button Demo");
buttonFrame.setSize( 350, 275 );
buttonFrame.setVisible( true );
}
Run Code Online (Sandbox Code Playgroud)
}
ButtonFrame 类:
public class ButtonFrame extends JFrame{
private final static Logger LOGGER = LogManager.getLogger(NewWindow.class);
JButton bChange;
JFrame frame = new JFrame("Our …
Run Code Online (Sandbox Code Playgroud) 在同步环境中,很容易创建一个范围上下文,允许您将带外上下文附加到当前线程.例如,当前的TransactionScope或线程静态日志记录上下文.
using (new MyContext(5))
Assert.Equal(5, MyContext.Current);
Assert.Equal(null, MyContext.Current);
Run Code Online (Sandbox Code Playgroud)
使用IDisposable和线程静态字段的组合可以轻松实现上下文.
显然,当使用异步方法时,这会分崩离析,因为上下文基于线程静态字段.所以,这失败了:
using (new MyContext(5))
{
Assert.Equal(5, MyContext.Current);
await DoSomethingAsync();
Assert.Equal(5, MyContext.Current);
}
Run Code Online (Sandbox Code Playgroud)
当然我们也希望将上下文传递给调用链中的异步方法,所以这也应该有效:
using (new MyContext(5))
{
Assert.Equal(5, MyContext.Current);
await AssertContextIs(5);
}
Run Code Online (Sandbox Code Playgroud)
有没有人知道如何实现这一点?使用async/await模式时丢失带外上下文会使代码的某些部分变得非常难看.
考虑异步WebAPI调用,您希望将基于请求的上下文用于日志记录.您希望调度堆栈深处的记录器能够知道请求ID,而无需使用参数将整个请求ID一直传递到调用堆栈.
谢谢你的帮助!