我想运行任意基于控制台的子流程,并从单个主流程管理它们.基于控制台的子进程通过stdin,stdout和stderr进行通信,如果在真正的控制台中运行它们,则在按CTRL + C时它们会完全终止.其中一些实际上可能是一个进程树,例如运行可执行文件的批处理脚本,该可执行文件又可以运行另一个可执行文件来完成某些工作.我想重定向他们的标准I/O(例如,以便我可以在GUI窗口中显示他们的输出)并且在某些情况下向他们发送CTRL + C事件,以便他们放弃并彻底终止.
以下两个图首先显示了正常结构 - 一个主进程有四个工作子进程,其中一些有自己的子进程; 然后当其中一个工作人员需要被停止时应该发生什么 - 它和它的所有孩子应该得到CTRL + C事件,但没有其他进程应该收到CTRL + C事件.
流程图http://pics.livejournal.com/clockworksaint/pic/0007z5yr/s640x480.png
此外,我更希望用户看不到额外的窗口.
这是我尝试过的(注意我在使用Python,但C的解决方案仍然有用):
CREATE_NEW_CONSOLE,然后让它产生工作进程.然后在我们要杀死worker时调用GenerateConsoleCtrlEvent(CTRL_C_EVENT,0).不幸的是,CREATE_NEW_CONSOLE似乎阻止我重定向标准I/O通道,所以我没有简单的方法将输出返回到主程序.CREATE_NEW_PROCESS_GROUP,然后让它产生工作进程.然后在我们要杀死worker时调用GenerateConsoleCtrlEvent(CTRL_C_EVENT,0).不知何故,此管理对CTRL + C发送只到主过程,这是完全无用的.仔细观察,GenerateConsoleCtrlEvent表示无法将CTRL + C发送到进程组.CREATE_NEW_PROCESS_GROUP.然后调用GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,pid)来杀死worker.这并不理想,因为CTRL + BREAK不如CTRL + C友好,可能会导致终止混乱.(例如,如果它是一个Python进程,则不能捕获KeyboardInterrupt并且不会运行finally块.)有什么好方法可以做我想要的吗?我可以看到理论上我可以在第一次尝试的基础上建立并找到其他方法在进程之间进行通信,但我担心它会变得非常尴尬.是否有其他程序可以达到同样效果的好例子?它似乎很简单,不能满足所有这一要求.
线程安全
此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的.任何实例成员都不保证是线程安全的.
System.Delegate的文档中存在相同的语句.
现在,代理人拥有一个不可变的API,但正如Eric Lippert所说:"认为仅仅因为数据结构不允许你改变其内容的任何方式是一种谬论,它的实现必须是线程安全的!"
从现有委托创建新委托的一些机制是静态方法:Delegate.Combine和Delegate.Remove.所以听起来这些都是线程安全的.给定多播代理A,B和C,我可以安全地将A和B组合在一个线程上制作D,同时将B和C组合在另一个线程上制作E.
但是调用委托不是静态方法.这是否意味着技术上我的代码可能会破坏,如果我在线程之间共享委托并在两者上调用它,或者如果我在一个线程上调用委托,而在另一个线程上将它与另一个线程组合?MulticastDelegate在这种情况下,符合标准的实现会导致未定义的行为吗?代表是否返回Combine或Remove保证不与任何其他代表共享任何隐藏的可变状态?
请注意,我在询问标准保证什么,而不是C#编译器和CIL JIT编译器的当前行为.通过实验,我可以确定在我可用的体系结构中使用.NET和Mono 确实看起来确实安全,但是我看不出是什么指定或保证了这种行为.
我想查询一个包含目录路径的SQLite表,以查找某个层次结构下的所有路径。这是该列内容的示例:
/alpha/papa/
/alpha/papa/tango/
/alpha/quebec/
/bravo/papa/
/bravo/papa/uniform/
/charlie/quebec/tango/
Run Code Online (Sandbox Code Playgroud)
如果我搜索下的所有内容/bravo/papa/,则希望获得:
/bravo/papa/
/bravo/papa/uniform/
Run Code Online (Sandbox Code Playgroud)
我目前正在尝试这样做(请参阅下文,了解为什么我不能使用更简单的方法的长篇故事):
SELECT * FROM Files WHERE Path >= '/bravo/papa/' AND Path < '/bravo/papa0';
Run Code Online (Sandbox Code Playgroud)
这可行。看起来有点怪异,但适用于此示例。“ 0”是大于“ /”的Unicode代码点1。当按字典顺序排序时,所有以'/ bravo / papa /'开头的路径都比较大且小于'bravo / papa0'。但是,在我的测试中,我发现当我们尝试以下方法时,这种情况会分解:
SELECT * FROM Files WHERE Path >= '/' AND Path < '0';
Run Code Online (Sandbox Code Playgroud)
这不会返回任何结果,但是应该返回每一行。据我所知,问题在于SQLite将'0'视为数字,而不是字符串。例如,如果我使用“ 0Z”而不是“ 0”,则可以得到结果,但是会带来误报的风险。(例如,如果实际上有一个条目“ 0”。)
我的问题的简单版本是:有没有办法让SQLite在这样的查询中将'0'视为包含Unicode字符'0'的length-1字符串(应该对字符串进行排序,例如'!','* '和'/',但在'1','='和'A'之前而不是整数0(哪个SQLite在所有字符串之前排序)?
我认为在这种情况下,我实际上可以摆脱对“ /”下所有内容的特殊搜索,因为我的所有条目始终都以“ /”开头,但是我真的很想知道如何避免这种情况总的来说,与Javascript的“ ==”运算符完全一样,这令人不愉快。
一种更自然的方法是使用LIKE或GLOB运算符。例如:
SELECT * FROM Files WHERE Path LIKE @prefix || '%';
Run Code Online (Sandbox Code Playgroud)
但是我想支持所有有效的路径字符,因此我需要对'_'和'%'符号使用ESCAPE。显然,这阻止了SQLite在Path上使用索引。(请参阅http://www.sqlite.org/optoverview.html#like_opt)我真的希望能够从这里的索引中受益,并且听起来像使用LIKE或GLOB都是不可能的,除非我可以保证它们都不目录名称中将出现特殊字符,并且POSIX允许使用NUL和'/'以外的任何内容,甚至GLOB的'*'和'?' 字符。
我提供这个是为了上下文。我对解决潜在问题的其他方法感兴趣,但是我更愿意接受一个直接解决SQLite中字符串看起来像数字的歧义的答案。
在该问题中,未引用这些值。即使将值用引号引起来或作为参数传递,我也得到这些结果。
编辑 -请在下面查看我的答案。该列是使用无效类型“ STRING”创建的,SQLite将其视为NUMERIC。
当该结构仅包含一个数组时,我无法使用 Python 的 ctypes 调用按值传递结构的本机代码。我在这里做错了吗?以下代码适用于某些类型和数组大小,但在其他类型和数组大小的情况下会因消息“ Aborted (core dumped)”而消失。当结构体的大小为 16 字节时,它似乎会失败。
这大致是我正在做的事情(有关完整的可运行版本,请参阅进一步的内容):
libsum = ctypes.cdll.LoadLibrary('./libsum.so')
class MyStruct(ctypes.Structure):
_fields_ = [("data", ctypes.c_uint32 * 4)]
m = MyStruct()
# ... initialize value of m ...
result = libsum.sum(m))
Run Code Online (Sandbox Code Playgroud)
为了调用这样声明的函数:
struct ArrayStruct {
std::uint32_t data[4];
};
extern "C" int64_t sum(struct ArrayStruct array);
Run Code Online (Sandbox Code Playgroud)
我在 64 位 Ubuntu 上运行它并尝试 Python 3.4 和 Python 2.7。在这两种情况下我都得到相同的结果——只要数组的大小在 9 到 16 字节之间,程序就会中止。
似乎我一定在做一些愚蠢的事情,但我无法弄清楚是什么。
libsum = ctypes.cdll.LoadLibrary('./libsum.so')
class MyStruct(ctypes.Structure):
_fields_ = [("data", ctypes.c_uint32 * 4)]
m = MyStruct()
# …Run Code Online (Sandbox Code Playgroud) 我有一些看起来像这样的R代码:
library(dplyr)
library(datasets)
iris %.% group_by(Species) %.% filter(rank(Petal.Length, ties.method = 'random')<=2) %.% ungroup()
Run Code Online (Sandbox Code Playgroud)
赠送:
Source: local data frame [6 x 5]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 4.3 3.0 1.1 0.1 setosa
2 4.6 3.6 1.0 0.2 setosa
3 5.0 2.3 3.3 1.0 versicolor
4 5.1 2.5 3.0 1.1 versicolor
5 4.9 2.5 4.5 1.7 virginica
6 6.0 3.0 4.8 1.8 virginica
Run Code Online (Sandbox Code Playgroud)
这种按物种分组,每组只保留最短的Petal.Length.我的代码中有一些重复,因为我对不同的列和数字执行了几次.例如:
iris %.% group_by(Species) %.% filter(rank(Petal.Length, ties.method = 'random')<=2) %.% ungroup()
iris %.% group_by(Species) %.% filter(rank(-Petal.Length, ties.method = …Run Code Online (Sandbox Code Playgroud) 我正在将sbt用于多项目构建,如下所述:
http://www.scala-sbt.org/0.13/tutorial/Multi-Project.html
这是顶级build.scala文件:
import sbt._
import Keys._
object ExampleBuild extends Build {
lazy val scrooge = Project(
id = "scrooge",
base = file("messages-scrooge")
)
lazy val examples = Project(
id = "examples",
base = file("examples")
).dependsOn(scrooge)
}
Run Code Online (Sandbox Code Playgroud)
我想更改目标目录,以便所有输出都进入一个单独的分区。*以下内容似乎可行,但确实很笨拙,因为我需要为每个子项目分别更改它。如果有更多的话,情况只会变得更糟:
target="$HOME/sbt-target"
sbt "project scrooge" "set target := new java.io.File(\"$target/scrooge\")" "project examples" "set target := new java.io.File(\"$target/examples\")" "project root" clean assembly
Run Code Online (Sandbox Code Playgroud)
我更喜欢执行以下操作,但是在“示例”项目试图从“导入”中输入类型的地方,它无法编译出许多有关“对象不是包的成员...”的消息。 scrooge”项目。我认为这是因为两个项目都踩着对方的输出文件。
target="$HOME/sbt-target"
sbt "set every target := new java.io.File(\"$target\")" clean assembly
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?我不介意更改构建文件,但我不希望在其中没有任何硬编码的路径。
*-我要更改输出目录的原因是我在Vagrant VM中进行构建,并且使用Virtualbox共享文件夹将源文件夹从Windows主机共享到Linux VM。Scala编译器尝试创建一些非常长的文件名,这些文件名超过Windows 260字符路径限制。如果您坚信我最好尝试以其他方式解决此问题,请告诉我,我将发布一个单独的问题,但是我已经朝着这个方向遇到了很多问题,因此我希望只需更改目标目录。
您将如何为大型C#解决方案布置目录结构,该解决方案可能包含20到30个项目,主要是C#,但有些是C++?你在哪里放置外部依赖?在源代码管理中创建分支时,您是否完全分支了所有内容?您是否覆盖构建文件的默认值?
现代 Oracle JDK 的版本号似乎包含不同数量的点线段。例如,此页面列出了以下版本号:
这不是语义版本控制,因为可以有三个以上的数字组件。四是(点分隔)数字组件的最大数量,还是可以有更多?这些数字的含义是什么?它们何时会增加?例如,与从 17.0.3 迁移到 17.0.3.1 相比,从 17.0.2 迁移到 17.0.3 有何说明?应如何提及每个数字(例如“主要”、“次要”或“补丁”)?有权威的资料来解释这个编号系统吗?