读取 - 复制 - 更新(RCU)是一种手动内存管理技术,在Linux内核中越来越流行.
是否有可能设计一种使用RCU而不是传统垃圾收集器的语言和VM来回收无法访问的内存?
我正在使用具有可编辑内容的代码构建GUI.当用户点击静态显示时,控件将换出允许编辑的控件.在某些情况下,显示控件(例如Label)被替换为一组控件,例如a ComboBox和TextBox.
我想检测何时从我的可编辑控件组中丢失焦点,以便将界面从编辑器切换回该项的显示表示.
例如,我可能在树中有一个GUI Panel1(Panel2(Button1, Button2), Button3),我想检测焦点丢失的时间Panel2.我尝试了以下(F#代码):
open System.Windows
let button1 = Controls.Button(Content="1")
let button2 = Controls.Button(Content="2")
let button3 = Controls.Button(Content="3")
[<System.STAThreadAttribute>]
do
let panel1 = Controls.StackPanel()
let panel2 = Controls.StackPanel()
panel2.Children.Add button1 |> ignore
panel2.Children.Add button2 |> ignore
panel1.Children.Add panel2 |> ignore
panel1.Children.Add button3 |> ignore
panel2.LostFocus.Add(fun _ ->
printfn "Panel2 lost focus")
Application().Run(Window(Content=panel1))
|> ignore
Run Code Online (Sandbox Code Playgroud)
将panel2.LostFocus在触发事件button3被点击后,button2已经被点击,符合市场预期,因为焦点,搬出panel1来button3.但是,即使从未失去焦点,button2点击后点击也会触发.button1panel2 …
我有一些看起来像这样的记录:
[<DataContract>]
type Rec1 = {
[<DataMember>] mutable field1 : int;
[<DataMember>] mutable field2 : string;
}
[<DataContact>]
type Rec2 = {
[<DataMember>] mutable field3 : Rec1;
[<DataMember>] mutable field4 : int;
}
Run Code Online (Sandbox Code Playgroud)
我DataContactJsonSerializer用来将JSON反序列化为这个结构.这是一个有效的JSON值:
{ "field3": null, "field4": 1 }
Run Code Online (Sandbox Code Playgroud)
这意味着在运行时,field3是null/Unchecked.defaultOf<_>.在Visual Studio 2010中,此测试工作正常:
(deserialize<Rec2> "{ field3: null, field4: 1 }") = { field3 = Unchecked.defaultOf<_>; field4 = 1 } //true
Run Code Online (Sandbox Code Playgroud)
在Visual Studio 2013中,相同的代码抛出NullReferenceException:
at Rec2.Equals(Rec2 obj)
Run Code Online (Sandbox Code Playgroud)
偷看ILSpy中的代码,我看到这是生成的:
if(this != null)
{
return …Run Code Online (Sandbox Code Playgroud) 如果我有一个字符串,1 2 3并且我确定包含a的子字符串的位置,double我如何直接从子字符串解析它而不创建临时字符串?
例如,我可以这样做System.Double.Parse(str.Substring(0, 1))但会创建一个缓慢且不必要的临时字符串.是否可以直接从原始字符串的一部分解析double?
编辑
Eric Lippert在这里质疑我的动机,说"小弦很便宜".这样做的动机来自于我对int的解析和看到大量的性能提升做同样的事情,因为显然,小字符串不是那么便宜.
这是一个通过临时字符串来修改一系列int的函数:
let lex f (s: string) =
let rec inside i0 (s: string, i) =
if i = s.Length then
f (s.Substring(i0, i-i0) |> System.Int32.Parse)
else
let c = s.[i]
if '0'<=c && c<='9' then
inside i0 (s, i+1)
else
f (s.Substring(i0, i-i0) |> System.Int32.Parse)
outside (s, i)
and outside (s: string, i) =
if i < s.Length then
let c = s.[i]
if '0'<=c && …Run Code Online (Sandbox Code Playgroud) OCaml GC强制执行全局锁定,以防止mutators(线程)并行运行,尽管它们可以并发运行(交错).我相信SML/NJ和MLton也是如此,但不是PolyML,GHC,F#,Clojure和Scala.
还有哪些其他功能语言实现允许线程并行运行?
以下测试代码(F#)未返回我期望的结果:
let safeCount() =
let n = 1000000
let counter = ref 0
let spinlock = ref <| SpinLock(false)
let run i0 i1 () =
for i=i0 to i1-1 do
let locked = ref false
try
(!spinlock).Enter locked
if !locked then
counter := !counter + 1
finally
if !locked then
(!spinlock).Exit()
let thread = System.Threading.Thread(run 0 (n/2))
thread.Start()
run (n/2) n ()
thread.Join()
!counter
Run Code Online (Sandbox Code Playgroud)
我希望SpinLock相互排除计数器,因此,它返回1,000,000的计数,但相反,它返回较小的值,好像没有发生互斥.
有什么想法有什么不对吗?
我有一个用C++编写的小型原型程序,在Linux下运行,使用该memalign函数来分配与页面等边界对齐的区域.在Visual C++中是否有等效的功能?
我正在学习x86汇编程序以编写编译器.特别是,我正在使用各种简单的递归函数并通过不同的编译器(OCaml,GCC等)提供它们,以便更好地理解不同编译器生成的汇编程序的种类.
我有一个简单的递归整数Fibonacci函数:
int fib(int x) { return (x < 2 ? x : fib(x-1)+fib(x-2)); }
Run Code Online (Sandbox Code Playgroud)
我的手工编码组件看起来像这样:
fib:
cmp eax, 2
jl fin
push eax
dec eax
call fib
push eax
mov eax, [esp+4]
add eax, -2
call fib
add eax, [esp]
add esp, 8
fin:
ret
Run Code Online (Sandbox Code Playgroud)
使用Intel-syntax汇编程序编译该函数gcc -O2会产生这个神秘的代码:
_fib:
push edi
push esi
push ebx
sub esp, 16
mov edi, DWORD PTR [esp+32]
cmp edi, 1
jle L4
mov ebx, edi
xor esi, esi
L3:
lea eax, [ebx-1] …Run Code Online (Sandbox Code Playgroud) 灵感来自Herb Sutter引人注目的演讲不是你父亲的C++,我决定再使用微软的Visual Studio 2010来看看最新版本的C++.我特别感兴趣的是Herb断言C++是"安全的",因为我没有听说过C++ 11解决了众所周知的向上funarg问题.据我所知,C++ 11无法解决这个问题,因此不"安全".
您不希望返回对局部变量的引用,因为本地是在函数返回后将不再存在的堆栈帧上分配的,因此,该函数将返回一个悬挂指针,指向已分配的内存,这将导致非 - 确定数据损坏.C和C++编译器知道这一点,并在您尝试将引用或指针返回到本地时发出警告.例如,这个程序:
int &bar() {
int n=0;
return n;
}
Run Code Online (Sandbox Code Playgroud)
导致Visual Studio 2010发出警告:
warning C4172: returning address of local variable or temporary
Run Code Online (Sandbox Code Playgroud)
但是,C++ 11中的lambdas可以很容易地通过引用捕获局部变量并返回该引用,从而产生等效的悬空指针.考虑以下函数foo返回一个lambda函数,该函数捕获局部变量n并返回它:
#include <functional>
std::function<int()> foo(int n) {
return [&](){return n;};
}
Run Code Online (Sandbox Code Playgroud)
这种看似无害的功能是内存不安全和损坏数据的来源.调用此函数将lambda放在一个位置然后调用lambda并在另一个地方打印它的返回值为我提供了这个输出:
1825836376
Run Code Online (Sandbox Code Playgroud)
此外,Visual Studio 2010不提供任何警告.
对我来说,这看起来像是一个非常严重的设计缺陷.即使是最简单的重构也可能会产生一个lambda交叉堆栈帧,无声地引入非确定性数据损坏.然而,似乎有关于这个问题的宝贵信息很少(例如,在StackOverflow上搜索"向上funarg"和C++没有提供命中).人们是否意识到这一点?有人在研究解决方案或描述变通方法吗?