首页 \ 问答 \ 释放闭包(Releasing closures)

释放闭包(Releasing closures)

在nodemcu上,我使用闭包通过套接字发送文件,如下所示:

function sendfile(sock, name)
    local fd = file.open(name, "r")

    function sendchunk()
        local data = fd:read()
        if data then
            sock:send(data)
        else
            fd:close()
            sock:close()
        end
    end

    sock:on("sent", sendchunk)
    sendchunk()
end

传输几个文件后,由于“内存不足”,解释器会发生混乱。 我可以想象这可能是由于关闭仍然悬挂。 垃圾收集器很难确定一旦文件和套接字关闭就不会再调用sendchunk()。

不幸的是,我的谷歌搜索没有透露一种方法来结束关闭并释放它正在使用的内存。

我使用错误的方法来做到这一点吗? 我应该使用匿名函数还是其他东西?


On a nodemcu, I'm using a closure to send a file over a socket, like this:

function sendfile(sock, name)
    local fd = file.open(name, "r")

    function sendchunk()
        local data = fd:read()
        if data then
            sock:send(data)
        else
            fd:close()
            sock:close()
        end
    end

    sock:on("sent", sendchunk)
    sendchunk()
end

After transferring a few files, the interpreter panics due to "not enough memory". I can imagine this may be due to closure still hanging around. It would be difficult for the garbage collector to determine that sendchunk() will not be called again once the file and socket are closed.

Unfortunately my googling has not revealed a method to end the closure and free the memory it is using.

Am I using a wrong method to do this? Should I perhaps use an anonymous function or something?


原文:https://stackoverflow.com/questions/49989331
更新时间:2021-11-26 22:11

最满意答案

我已经找到了你的问题的合理副本,但只找到了有关假情报答案的问题。 所以:

您看到的窗口不是命令解释器,它是与命令解释器使用的窗口类似的窗口。 这些称为控制台窗口 。 您的可执行文件会生成一个新的控制台窗口,因为它默认标记为需要一个,因此当它不在控制台窗口中运行时,Windows会为它创建一个新窗口。

标记是可执行文件标题中的一个值,称为Windows子系统 ,它确定Windows需要哪些基本服务,Windows应如何处理它。 默认情况下,MinGW工具(以及标准代码,Microsoft的工具)使用控制台子系统生成可执行文件。 通常,用于普通应用程序的唯一其他子系统是GUI子系统 ,它与控制台子系统类似,只是它表示不需要控制台窗口。

使用MinGW g ++,您可以使用半文档选项-mwindows来生成带有GUI子系统的可执行文件。

或者,您可以为链接器指定[1] ,例如-Wl,-subsystem,windows

显然,在NetBeans中,您必须修改项目属性中的编译器/链接器选项。

对于其他IDE,它可以像通过复选框或列表中选择子系统一样简单。


使用MinGW工具,您可以通过objdump实用程序检查子系统。 还有其他方式。 但是,使用objdump

C:\my\forums\so\070>objdump -p a.exe | find /i "sub"
MajorSubsystemVersion   5
MinorSubsystemVersion   2
Subsystem               00000003        (Windows CUI)

C:\my\forums\so\070>g++ foo.cpp -mwindows

C:\my\forums\so\070>objdump -p a.exe | find /i "sub"
MajorSubsystemVersion   5
MinorSubsystemVersion   2
Subsystem               00000002        (Windows GUI)

C:\my\forums\so\070> _

使用Microsoft的工具,您可以类似地使用其dumpbin实用程序。

还有许多其他标头转储实用程序,但[2] Windows本身不提供可执行文件的子系统。


使用Microsoft的工具,没有像g ++ -mwindows这样的编译器选项,但是有一个子系统链接器选项 /subsystem:windows 。 使用此标准和符合标准的代码,还必须将机器代码级别入口点指定为调用标准main 入口点 。 即,链接器选项/entry:mainCRTStartup

C:\my\forums\so\070>cl std.cpp /Feb
std.cpp

C:\my\forums\so\070>dumpbin /headers b.exe | find /i "sub"
            6.00 subsystem version
               3 subsystem (Windows CUI)

C:\my\forums\so\070>cl std.cpp /Feb /link /subsystem:windows /entry:mainCRTStartup
std.cpp

C:\my\forums\so\070>dumpbin /headers b.exe | find /i "sub"
            6.00 subsystem version
               2 subsystem (Windows GUI)

C:\my\forums\so\070> _

对于在命令行中工作,可以通过使用LINK环境变量稍微简化一下。

许多人宁愿使用微软的monstrosity main功能替换,称为WinMain 。 这指导Microsoft的链接器默认采用GUI子系统。 当人们希望从代码的角度来看没有意义,并且是不可移植的(特别是g ++接受函数但忽略其子系统提示)时,它使控制台子系统更难以构建[3] ,以及可怕的冗长。


[1] -mwindows选项通常会添加一些常用的Windows API库,而不是由简单的子系统链接器选项添加。 您可以通过-dumpspecs选项转储配置来检查哪些库。
[2]我在这里谈论现代Windows。 在20世纪90年代后期,Windows 9.x确实通过其(现已停止的)“快速查看”功能呈现子系统值。 对于可执行文件,显然只是从dumpbin提供了完整的文本输出。
[3]使用Microsoft的工具, WinMain主函数和指定的控制台子系统,默认情况下,链接器会抱怨main缺失。 然后一个修复是链接器选项/entry:WinMainCRTStartup


I've looked for a reasonable duplicate of your question, but found only questions with disinformation answers. So:

The window you see is not the command interpreter, it's a window of the same kind as used by the command interpreter. These are called console windows. Your executable produces a new console window because it is by default marked as requiring one, so when it's not run from within a console window, Windows creates a new one for it.

The mark is a value in the executable file's header called its Windows subsystem, which determines what basic services it needs from Windows, how Windows should treat it. By default the MinGW tools (and also, for standard code, Microsoft's tools) produce an executable with the console subsystem. Usually the only other subsystem used for an ordinary application is the GUI subsystem, which is just like the console subsystem except that it says a console window is not required.

With MinGW g++ you can use the half-documented option -mwindows to produce an executable with GUI subsystem.

Alternatively you can specify [1]that to the linker, like -Wl,-subsystem,windows.

Apparently in NetBeans you have to modify the compiler/linker options in the project properties.

With other IDEs it can be as simple as choosing the subsystem via a check-box or in a list.


With the MinGW tools you can check the subsystem via the objdump utility. And also in other ways. But, using objdump:

C:\my\forums\so\070>objdump -p a.exe | find /i "sub"
MajorSubsystemVersion   5
MinorSubsystemVersion   2
Subsystem               00000003        (Windows CUI)

C:\my\forums\so\070>g++ foo.cpp -mwindows

C:\my\forums\so\070>objdump -p a.exe | find /i "sub"
MajorSubsystemVersion   5
MinorSubsystemVersion   2
Subsystem               00000002        (Windows GUI)

C:\my\forums\so\070> _

With Microsoft's tools you can similarly use their dumpbin utility.

There are also many other header dump utilities, but [2]Windows does not itself present the subsystem of an executable.


With Microsoft's tools there is no compiler option like g++ -mwindows, but there is a subsystem linker option, /subsystem:windows. With this, and standard-conforming code, one must also specify the machine code level entry point as the one that calls standard main. Namely, linker option /entry:mainCRTStartup.

C:\my\forums\so\070>cl std.cpp /Feb
std.cpp

C:\my\forums\so\070>dumpbin /headers b.exe | find /i "sub"
            6.00 subsystem version
               3 subsystem (Windows CUI)

C:\my\forums\so\070>cl std.cpp /Feb /link /subsystem:windows /entry:mainCRTStartup
std.cpp

C:\my\forums\so\070>dumpbin /headers b.exe | find /i "sub"
            6.00 subsystem version
               2 subsystem (Windows GUI)

C:\my\forums\so\070> _

For working in the command line this can be a little simplified by using the LINK environment variable.

Many prefer to instead use Microsoft's monstrosity main function replacement, called WinMain. This guides Microsoft's linker to assume the GUI subsystem by default. It makes it more [3]difficult to build with console subsystem when one desires that, is meaningless from a code point of view, and is non-portable (in particular, g++ accepts the function but ignores its subsystem hinting), as well as horrendously verbose.


[1] The -mwindows option typically adds some often used Windows API libraries, not added by the simple subsystem linker option. You can check which libraries by dumping a config via the -dumpspecs option.
[2] I'm talking here about modern Windows. Windows 9.x, in the late 1990s, did present the subsystem values via its (now discontinued) “Quick View” functionality. Which, for an executable, apparently just presented the full textual output from dumpbin.
[3] With Microsoft's tools, a WinMain main function, and console subsystem specified, by default the linker will complain about a missing main. One fix is then the linker option /entry:WinMainCRTStartup.

相关问答

更多
  • 也许你没有在你的计算机上安装(或注册)这个ActiveX控件。 每个Windows中都应该找到WScript.Shell : var run=new ActiveXObject('WSCRIPT.Shell').Run("commands to run"); 如果commands to run有空格,则需要使用双引号。 编辑 以下内容主要来自MSDN: http : //msdn.microsoft.com/en-us/library/windows/desktop/gg537745 (v= vs.85) ...
  • 我已经找到了你的问题的合理副本,但只找到了有关假情报答案的问题。 所以: 您看到的窗口不是命令解释器,它是与命令解释器使用的窗口类似的窗口。 这些称为控制台窗口 。 您的可执行文件会生成一个新的控制台窗口,因为它默认标记为需要一个,因此当它不在控制台窗口中运行时,Windows会为它创建一个新窗口。 标记是可执行文件标题中的一个值,称为Windows子系统 ,它确定Windows需要哪些基本服务,Windows应如何处理它。 默认情况下,MinGW工具(以及标准代码,Microsoft的工具)使用控制台子系 ...
  • 首先,您需要当前CMD实例的PID。 这里讨论的主题。 我会为你提供我的解决方案 - getCmdPID.bat 这是脚本(getCmdPID应该在同一目录中): @echo off call getCmdPID set "current_pid=%errorlevel%" for /f "skip=3 tokens=2 delims= " %%a in ('tasklist /fi "imagename eq cmd.exe"') do ( if "%%a" neq "%current_pid ...
  • 虽然我没有亲自测试,我有充分的理由相信上述的AT COMMAND解决方案将适用于XP,2000和Server 2003.根据我和Bryant的测试,我们已经确定了同样的方法不适用于Vista或Windows Server 2008 - 可能是由于增加的安全性和/交互式交换机已被弃用。 但是,我遇到了这篇文章 ,它演示了使用SysInternals (由Microsoft于2006年7月收购)的PSTools 。我通过以下命令启动了命令行,突然间我在本地管理帐户下运行,如魔术: psexec -i -s cm ...
  • 你学习cmd和C的巨大努力! 但是,我认为你混淆了文件的扩展名(名称)及其内容。 当你告诉gcc生成一个可执行文件时,你可能想给它一个.exe扩展名,就像你说的那样,假设你的源名为“myprog.c”: gcc -o myprog.exe myprog.c 这应该始终生成一个myprog.exe文件。 但没有什么可以阻止你像这样调用它:gcc -o myprog.myFancyExtension myprog.c 您仍然可以通过cmd运行程序(虽然我没有在Windows上测试)。 请注意,在Linux等其 ...
  • 显示控制台似乎是默认行为。 你可以通过-w,--windowed, - noconsole来改变它 见这里: http : //www.pyinstaller.org/export/develop/project/doc/Manual.html showing console seems to be the default behaviour. you may change this via -w, --windowed, --noconsole see here: http://www.pyinstall ...
  • 你不需要运行exe通过cmd 。 这应该足够了: Runtime.getRuntime().exec("file.exe", null, projDir); 和通过cmd: Runtime.getRuntime().exec(new String[]{"cmd","/c","start file.exe"}, null, projDir); Thank you all for your help, I found a parallel way to run the exe file, and this ...
  • 我刚刚注意到你将整个术语包含在一组额外的双引号中,并使用了linux正斜杠 - 尝试这个批处理文件,并查看控制台上是否有任何错误消息。 @echo off cd /d "%userprofile%\Desktop\mplus" "C:\Program Files\Mplus\Mpluswin.exe" "test_mplus.inp" echo mplus was launched pause I've just noticed that you enclosed the entire term in a ...
  • 该错误已得到解决。 问题是第三方dll应该出现在存在iron python可执行文件的文件夹中。 例如,如果文件夹C:\ Program Files(x86)\ Iron Python2.7中存在ipy.exe,那么第三方dll必须存在于那里。 我花了这么长时间才弄明白这一点的原因是因为当我使用第三方提供的以前版本的dll时,没有必要在路径C:\ Program Files(x86)\ Iron中复制dll Python2.7 。 但对于新版本,我必须这样做。 奇怪的是!! The error has be ...
  • 我讨厌启动其他应用程序并尝试控制它们。 如果可能的话,我建议尝试以编程方式模仿msg.exe的功能。 从做一些快速的谷歌搜索,我发现msg.exe使用的API函数显然是WTSSendMessage中的WTSSendMessage。 这是关于该功能的MSDN文章: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383842(v=vs.85).aspx 这是一个链接,显示如何从.NET调用该API函数: http://www.pinvoke. ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)