编程语言中的每个函数调用/块都在单独的线程中完成?[关闭]


26

我目前正在创建一种有趣的编程语言,其思想是每个函数调用/新块(如果有子句,循环等)将在单独的线程中工作。它不是自动创建新线程,而是应该自动执行该标准,并且如果您希望它在主线程中运行,则必须指定它。

我对多线程并行编程的了解不多,但是我知道一些基础知识(期货,线程安全对象)。因此,我想知道这样的语言在语法上看起来如何明智,甚至是否有可能以它开头?目标不是使它“有用”,更多是为了它的乐趣和学习经验。

(很抱歉,如果这是错误的发帖地点。如果是这样,请将您指向允许我这样的问题的正确地点,我将不胜感激。)


17
创建线程很简单。多线程的诀窍是当他们需要彼此交谈或使用相同资源时。换句话说,困难不是分叉,而是联接。您需要解决的主要问题是如何控制它。
JimmyJames

20
IMO,如果不认真扩展单词“ function”或“ thread”的通常定义,您将无法做到这一点。如果您还不熟悉演员,则可能需要阅读有关演员的信息en.wikipedia.org/wiki/Actor_model
Solomon Slow,

9
足够细粒度,您会发现CPU已经自动并行化指令,而不会给软件开发人员带来任何额外负担。请参阅序执行超标量处理器
8bittree '17

8
这听起来确实令人恐惧。我将解释原因,但卡尔·比勒费尔特(Karl Bielefeldt)已经这样做了。
梅森惠勒

1
您想用您的语言支持哪种范例?它是必须的还是功能性的?您是说所有语句将在同一时间执行-然后/其他块以及它们之后的内容?
Bergi

Answers:


39

每个函数调用/新块(如果有子句,循环等)将在单独的线程中工作。

阅读更多有关延续延续传递样式(以及它们与线程或协程的关系)的信息,我建议阅读SICPLisp In Small Pieces。另外,“ 编程语言实用程序”提供了几种语言的有用概述,并可以帮助您设计自己的语言。

因此,我想知道这样的语言在语法上如何看待

语法对于探索思想并不重要。语义更重要。我建议首先采用类似S-expr的语法(以便您可以首先使用Scheme及其call / cc进行原型制作)。

一旦您的想法更清晰(经过一些实验),您可以在lambda-the-ultimate上进行讨论,可以定义一个更性感的语法(如果您希望人们采用您的语言,这实际上很重要,而质量也很重要)实施,免费软件示例实施,文档,标准库,外部功能接口等)


25
+1表示语法无关紧要。如果可以解释语法为什么非常重要,则另加+1。
约尔格W¯¯米塔格

很好的建议,但是要讨论LtU上的内容,您需要一个帐户,并且从我的经验中获得一个帐户并不容易。
Mael

1
您应该使用线程池来减少开销。en.wikipedia.org/wiki/Thread_pool
shawnhcorey

37

您可能对阅读有关并行Haskell数据的研究感兴趣。如果您在youtube上搜索,Simon Peyton Jones也提供了一些与此主题相关的有趣演讲。

如果我从他的演讲中正确回忆起,在纯函数式编程中,找到创建线程的机会几乎是微不足道的。他在他的研究的主要问题是有太多的过短的寿命,从而创建线程,并传达他们的成果的开销基本上是远远超过并行处理的益处。例如,教编译器启动100个线程进行计算很容易sum $ fmap (+1) <100 length vector>,但是开销会使其值得吗?

然后,诀窍是将线程合并为有用的大小,而不会给程序员增加手动表示该代码的负担。为了有效地使用具有数千个内核的未来PC,这是一个棘手的问题。


8
我已经很乐意使用只有数百个内核的老式PC ...
Hagen von Eitzen

8
我要指出的是,对于大量数据并行设计,我们已经非常有效地进行了很多并行化:GPU本质上是200-1000台核心机器(甚至它们都有自己的内存层次结构)。
Delioth '17

4
@HagenvonEitzen:Azul Vega JCA(Java计算设备)具有16个CPU,每个54个内核,总共864个内核,这不是研究级或原型机,而是真正的产品。它也没有填满整个建筑物甚至整个房间,而是台式大小的设备。它在9年前可用。已经提到了GPU,但这是一台具有864个通用 CPU内核的机器。
约尔格W¯¯米塔格

3
当然,还有一个原因,我们有那些海量数据并行GPU的今天,但不再是这些庞大的多核心CPU的台式机。前者在商业上可行,而后者则不可行,这是因为您无法有效地对其编程。
MSalters'17

@MSalters也许我们只需要无限数量的猴子?或者,仅在每个步骤运行所有可能操作的Quantum程序?

15

这正是Erlang所做的。它主要通过使用队列来处理重新加入线程。这是一个很棒的概念,但是如果您的背景是更多过程类型的语言,那么一开始您很难理解。我强烈建议您调查一下。


4

首先,我建议您看一下PROMELA,这是一种用于描述并发算法的语言,以便模型检查器可以强制执行所有可能的执行,以验证它是否具有不正确的行为。(众所周知,并发编程很难正确执行,这就是为什么这种验证技术很重要的原因。)它并没有在单独的线程中运行所有构造,但是它确实具有相当奇怪的语法和语义,因为它的重点是并发程序的不确定性

变得更加抽象,π演算是对并行计算进行建模的一种很好的方法。除非您得到Robin Milner 所著的《通信和移动系统:Pi演算》一书,否则很难直言不讳。它帮助我从更广泛的意义上考虑了并行计算,即“多个线程访问共享内存”。十分有趣的是如何可以从更简单的自然并行原语构建条件语句“ gotos”等。

关于语法...解决此问题的最佳方法是编写一些示例程序。编写程序以对数组进行排序,或者同时对多个服务器执行ping操作并报告响应速度最快的服务器,或者尝试并行解决迷宫问题,或者什么都没有。在执行此操作时,语法中缺少的内容将变得显而易见,您可以添加它们。在添加了几件事之后,问问自己它们是否有共同点,如果是,也许您可​​以找到一种可以用于多种目的的简单方法。


4

过去曾尝试过类似的项目。我建议阅读经典著作以获取创意。(所有链接都转到维基百科)

  • Unity 这种语言曾经/曾经被用来教授并行编程。我认为它实际上并没有实现。语法有些含糊,但基本上,您有一组语句以未知顺序执行,并且重复执行直到无所事事为止。这最接近您的要求。

  • Occam 该语言是为实际使用而设计的,但从未真正流行。这里有一个关键字PAR,这意味着应并行执行语句列表。

  • Erlang另一种现实世界的语言。这是电信公司爱立信使用的,并且有很多。他们在使并行性实用和可用方面进行了大量工作。

  • Google GO这是我最喜欢的一堆。从概念上讲,它与Erlang相似,但语法更好,并且Google的重量更胜一筹。有什么可能会出错?

最后,我要警告一句:并行性很难正确实现。现代程序中的大多数错误是由于错误而导致的。您确定要去那里吗?


没有针对我清单之外的任何语言的冒犯。只是我的知识有限。
Stig Hemmer

3

可能,但对于99%以上的所有可想到的应用程序都没有用。逻辑通常是顺序约束的,是流程。您可以逐步解决问题,而步骤的顺序也很重要,这主要是因为一个步骤的输出将输入到下一个步骤。

在少数情况下,您确实有很多任务可以相互独立执行,通常在将它们并行运行之前先进行顺序设置会很便宜。

因此,我认为您最好花时间学习如何在自己喜欢的编程语言中使用多线程功能。


5
对于不同的问题,这是一个很好的答案。OP并不是在问这种方案的智慧,而只是在问它是否可以实现以及“语法”是什么样。
DepressedDaniel'17

9
那些不要求它的人最需要我的智慧。如果有人问是否有可能从购物车中爬下山坡,最好的答案不是“您打赌!确保给车轮加油!”。它更像是“嗯,是的,但是...”。
马丁·马特

让我想起了旧的EIAO汇编语言指令- 以任意顺序执行。(那键在哪里呢?)

@MartinMaat没有人会通过编写有趣的编程语言来自杀
user253751

2

Clojure可能值得一试。

http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

这里有一些想法:如果我们将一个可以独立执行的计算单元称为一个任务:1.任务是独立的,因此可以并发运行。2.不同的任务需要不同的资源并花费不同的时间才能运行3.因此,应计划任务以获得最大吞吐量4.唯一可以用作调度程序的程序是操作系统

苹果大型中央调度程序之类的事情就是提供这种调度程序的一种尝试。

以上意味着执行任务的责任不一定是编程语言的责任。

第二个想法是尽可能减少对并行系统进行编程的负担。做到这一点的唯一方法是从程序中删除任何有关如何进行操作的规范。程序仅应指定应执行的操作,其余应自动进行。

以上可能意味着动态语言和及时编译是必经之路。


2

您正在寻找的被称为隐式并行机制,并且有一些语言已经探索了这个概念,例如Sun / Oracle的Fortress。除其他事项外,它(潜在地)并行运行循环。

不幸的是,它已经停产了,并且那里有很多无效链接,但是如果您用Google努力的话,仍然可以在附近找到一些PDF:

https://www.eecis.udel.edu/~cavazos/cisc879-spring2008/papers/fortress.pdf(语言规范)

http://stephane.ducasse.free.fr/Teaching/CoursAnnecy/0506-Master/ForPresentations/Fortress-PLDITutorialSlides9Jun2006.pdf

http://www.oracle.com/technetwork/systems/ts-5206-159453.pdf

http://dl.acm.org/citation.cfm?id=1122972(收费墙)

值得注意的是,您通常不希望为每个语句/表达式启动一个实际的线程,因为创建和启动线程往往很昂贵-相反,您将拥有需要在其中发布一些工作的线程池。但这是一个实现细节。


1
+1提及要塞...我非常喜欢这种语言的想法。当他们宣布开发被终止时,我感到非常难过……
Roland Tepp

2

虽然不是这样的编程语言,但您应该看看VHDL。它用于描述数字电路,它自然可以并行执行所有操作,除非您明确要求串行执行。它可能会给您一些想法,包括如何设计语言以及可能适合哪种逻辑。


0

这可以用C ++轻松地模拟。只要确定“每个” *函数调用是由实现的即可std::future。简单地通过调用Future处理返回值.get()

因此,您可以通过编译为C ++来原型化语言。这也告诉我们语法是什么样的:主要区别是您将调用点(提供输入参数的地方)与返回点(使用函数输出的地方)分开。

(*)我说的是“每个功能”,但取决于您的是哪个功能。是memset内在的还是函数的?整数分配或用户定义类型的分配是函数调用吗?


而且,如果您将回答问题的时间推迟足够长的时间,通常对答案的需求就会消失。我认为这被称为“惰性存在”。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.