众所周知,现代操作系统具有线程调度程序,可以根据您的代码不了解的内部逻辑来选择不同的顺序来调度线程。通常,您设计多线程代码以确保强加给您的这种不确定性不会对您的输出产生有意义的影响。
这里的目标是相反的。产生一个程序,该程序以[0,99]为间隔打印整数,但由于OS线程调度程序的原因,该顺序因运行而异。
您必须实现“足够的不确定性”,定义为:
在10个试验的10个顺序集合中,您的程序必须在每个试验中至少产生9个唯一排列。在连续成功的10个测试中,您可能会有相当数量的失败尝试。
或者,换句话说,您需要运行100次程序,其中每10次运行的程序块最多具有两次输出相同结果的运行。
因此,偶尔将98和99交换不会减少费用。
这是一个代码高尔夫球,因此使用最少字节的答案将获胜。
细节
- 将输出写入标准输出,每行一个条目
- 如果您通过让两个线程将字符写入stdout(甚至偶尔)交织字符来破坏格式(导致偶发三位数或空行的情况),则结果无效
- 上述规则的唯一例外是,您可以在打印最后一个所需的数字后发出一个空行(不客气)
- 如果错过或重复任何必需的值,则结果无效
- 您的程序不必在单个核心处理器上具有不确定性(尽管是赞誉的)
- 如果您的程序仍然可以满足挑战的其他要求,并且线程系统是您的语言或您的语言的标准库的一部分,则您的程序可能使用实际上不受OS内核管理的绿色线程/纤维。
- 在现代处理器上,程序的运行时间必须可靠地在5秒以内
- 您不必指定在程序之外发生的环境更改,例如等待或设置更改。无论程序是连续运行100次还是每次运行之间有一个小时还是并行运行100次,您的程序都应该通过(这实际上可能会有所帮助...)
- 您可以使用诸如GPU或Xeon Phi之类的协处理器及其自身的内部调度机制来执行任务。规则适用于此的方式与适用于绿色线程的方式相同。
- 只要遵守本文中指定的规则,就可以通过各种睡眠,良率和其他技巧来激发调度程序
禁止操作
允许使用不确定性的唯一来源是调度程序调度线程运行的时间。以下列表并非详尽无遗,仅是为了提供一些示例,这些示例是您接受其他不确定性来源时被禁止执行的操作。
- 直接或间接访问任何种类的PRNG或硬件RNG功能(除非它是调度程序的固有部分)。
- 读取任何类型的输入(系统时间,文件系统,网络等)
- 读取线程ID或进程ID
- 自定义操作系统调度程序;您必须使用主流操作系统中的标准操作系统调度程序
- 也禁止自定义绿色线程/光纤调度程序。这意味着,如果您为此挑战编写语言,则必须使用OS线程。
答案验证
最好在所有常见的OS和现代处理器上都可以找到答案,并根据支持的广度来授予荣誉。但是,这不是挑战的要求。答案至少必须支持一个现代的SMP处理器和现代的操作系统。我将在硬件可用性方面测试主要答案。
- 如果您的输入将不会在运行Windows 10 v1607 x64的i7 5960x上产生所需的输出,请指定所需的环境
- 如果可以通过VMWare Workstation轻松复制,请提供确切的OS和VM规格
- 如果在上述两种情况下均无法生成,请同时记录测试内容的屏幕截图,如标题部分所述,并通过鼠标和键盘的交互作用(或任何非标准计算的控制方案)对屏幕进行手持视频录制设备使用)清晰可见,并将两个视频以及您的答案一起发布,并说明其工作原理
- 或者,使用匹配的硬件找一个久负盛名的长期用户(不是您)来重现结果并为您提供担保
- 如果您的输入使用的是外来编程语言,而典型的开发人员将不会被设置为编译/编辑/解释,请提供安装说明
- 如果您输入的内容取决于特定版本的JVM / Python解释器/其他版本,请指定
- 如果要在我的测试中连续进行10次以上的连续试验需要花费超过10分钟的时间,那么您将失败(因此,不要让成功的情况异常发生,尤其是当您处于较高水平时)运行时绑定)