모든 함수 호출 / 차단이 별도의 스레드에서 수행되는 프로그래밍 언어? [닫은]


26

나는 현재 모든 함수 호출 / 새로운 블록 (if 절, 루프 등)이 별도의 스레드에서 작동한다는 아이디어가 재미있는 프로그래밍 언어를 만들고 있습니다. 새 스레드를 만드는 대신 표준에서 자동으로 수행해야하며 기본 스레드에서 실행하려면 해당 스레드를 지정해야합니다.

나는 다중 스레드, 병렬 프로그래밍에 대해서는 알지 못하지만 기본 사항 (미래, 스레드 안전 객체)을 알고 있습니다. 따라서 나는 그러한 언어가 어떻게 현명하게 구문 적으로 보일 수 있는지, 그리고 심지어 시작하는 것이 가능한지 궁금합니다. 목표는 "유용한"것이 아니라 재미와 학습 경험을위한 것입니다.

(이것이 게시하기에 잘못된 곳이라면 죄송합니다. 그렇다면 내 것과 같은 질문이 허용되는 올바른 장소를 알려 주시면 기쁩니다.)


17
스레드를 만드는 것은 간단합니다. 멀티 스레딩의 비결은 서로 대화하거나 동일한 리소스로 작업해야 할 때입니다. 다시 말해, 힘든 것은 포크가 아니며 조인입니다. 당신이 해결해야 할 가장 큰 문제는 그것을 통제하는 방법입니다.
JimmyJames

20
IMO, "function"또는 "thread"라는 단어의 일반적인 정의를 심각하게 확장하지 않으면 그렇게 할 수 없습니다. 배우 에 대해 잘
Solomon Slow

9
충분히 세분화하면 CPU가 소프트웨어 개발자에게 추가적인 부담을주지 않으면 서 명령어를 자동으로 병렬 처리하는 것을 알 수 있습니다. 비 순차적 실행슈퍼 스칼라 프로세서를 참조하십시오 .
8bittree

8
실제로 끔찍한 소리가납니다. 나는 이유를 설명하려고했지만 Karl Bielefeldt는 이미 그랬습니다.
메이슨 휠러

1
당신의 언어로 어떤 종류의 패러다임을 지원하고 싶습니까? 필수적이거나 기능적이어야합니까? 당신은 모든 문장들이 동시에 실행될 것이라고 말하고 있습니까-그다음에 나오는 것과 함께 then / else-blocks?
Bergi

답변:


39

모든 함수 호출 / 새 블록 (if 절, 루프 등)은 별도의 스레드에서 작동합니다.

SICP & Lisp In Small Pieces 를 읽는 것이 좋습니다 계속연속 전달 스타일 (및 스레드 또는 코 루틴과의 관계)에 대해 자세히 읽으십시오 . 또한 Programming Language Pragmatics 는 여러 언어에 대한 유용한 개요를 제공하며 자신의 언어를 디자인하는 데 도움이됩니다.

따라서 나는 그러한 언어가 어떻게 현명하게 구문을 보일 수 있는지 궁금합니다.

구문은 아이디어 를 탐구하는 데별로 중요하지 않습니다 . 의미론이 훨씬 중요합니다. 먼저 구문과 같은 S-expr 을 채택하는 것이 좋습니다 (Scheme 및 call / cc를 사용하여 프로토 타입을 만들 수 있음 ).

일단 당신의 아이디어가 더 명확 해지면 (어떤 실험 후에) 람다에 대해 토론 할 수 있습니다 . 더 섹시한 구문을 정의 할 수 있습니다. 구현, 무료 소프트웨어 샘플 구현, 문서, 표준 라이브러리, 외부 기능 인터페이스 등)


25
구문이 관련이없는 이유는 +1입니다. 구문이 왜 중요한지 설명 할 수 있다면 또 하나의 +1입니다.
Jörg W Mittag

좋은 제안이지만 LtU에 관한 내용을 논의하려면 계정을 원하고 내 경험에서 계정을 얻는 것이 쉽지는 않습니다.
Mael

1
오버 헤드를 줄이려면 스레드 풀을 사용해야합니다. en.wikipedia.org/wiki/Thread_pool
shawnhcorey

37

데이터 병렬 Haskell 에 대한 연구에 관심이있을 수 있습니다 . YouTube에서 검색하면 Simon Peyton Jones가 주제와 관련된 흥미로운 대화를 나 has습니다.

순수한 기능 프로그래밍에서 그의 대화에서 올바르게 기억한다면 스레드를 만들 수있는 기회를 찾는 것은 거의 사소한 일입니다. 그의 연구에서 그의 주요 문제는 너무 많은 수명이 너무 길어서 스레드를 생성하고 그 결과를 전달하는 오버 헤드가 본질적으로 병렬 처리의 이점을 능가한다는 것입니다. 예를 들어, 컴파일러에게 100 개의 스레드를 계산하여 계산하도록 가르치는 것은 쉽지만 sum $ fmap (+1) <100 length vector>오버 헤드가 가치가 있습니까?

그런 다음 프로그래머가 스레드를 수동으로 표시하는 부담을주지 않으면 서 스레드를 유익한 크기로 통합합니다. 수천 개의 코어가있는 미래의 PC를 효과적으로 사용하려면 크랙이 필요한 어려운 문제입니다.


8
나는 이미 코어의 수백 ...과 oldfashioned PC와 함께 작동하도록 드리겠습니다
하겐 폰 Eitzen

8
많은 데이터 병렬 설계의 경우 이미 많은 병렬 처리를 매우 효율적으로 수행하고 있습니다 .GPU는 본질적으로 200-1000 코어 시스템입니다 (자체 메모리 계층 구조도 갖추고 있음).
Delioth

4
@HagenvonEitzen : Azul Vega JCA (Java Compute Appliance)에는 총 864 개의 코어에 대해 각각 54 개의 코어가있는 16 개의 CPU가 있으며 일부 연구 수준 또는 프로토 타입 머신이 아니라 실제 제품이었습니다. 또한 전체 건물이나 전체 공간을 채우지 않았으며 책상 크기의 기기였습니다. 그리고 9 년 전에 사용 가능했습니다. GPU는 이미 언급되었지만 864 개의 범용 CPU 코어 가있는 머신이었습니다 .
Jörg W Mittag 2012

3
물론, 우리가 왜 이유가 않습니다 그 거대한 멀티 코어 CPU가 데스크톱의 더 이상 그 대용량 데이터 병렬 GPU의 오늘을 가지고 있지만. 전자는 상업적으로 실행 가능하고 후자는 그렇지 않으며 효율적으로 프로그래밍 할 수 없기 때문입니다.
MSalters

@MSalters 아마도 우리는 무한한 수의 원숭이가 필요할까요? 또는 각 단계에서 가능한 모든 작업을 간단하게 실행하는 Quantum 프로그램?

15

이것이 바로 Erlang이하는 일입니다. 주로 대기열을 사용하여 스레드 재결합을 처리합니다. 훌륭한 개념이지만 배경이 절차 형 언어 인 경우 처음에는 머리를 감싸기가 약간 어렵습니다. 나는 그것을 조사하는 것이 좋습니다.


4

먼저 모델 알고리즘 이 잘못된 동작을 수행 할 수 없는지 확인하기 위해 가능한 모든 실행을 무차별 적으로 수행 할 수 있도록 동시 알고리즘을 설명하는 데 사용되는 언어 인 PROMELA 를 살펴 보는 것이 좋습니다 . (동시 프로그래밍은 제대로 이해하기 어려운 것으로 악명이 높기 때문에 이러한 검증 기술이 중요한 이유입니다.) 모든 구문을 별도의 스레드로 실행하지는 않지만 동시 프로그램 의 비결 정성 에 중점을두기 때문에 구문과 의미가 다소 이상합니다 .

더 추상적으로, π- 미적분 은 병렬 계산을 모델링하는 아름다운 접근 방식입니다. Robin Milner의 Communicating and Mobile Systems : The Pi Calculus 책을 얻지 않으면 머리를 숙이고하기가 어렵다 . "공유 메모리에 액세스하는 다중 스레드"라는보다 넓은 의미에서 병렬 계산에 대해 생각하는 데 도움이되었습니다. 조건문, "고 토스"등을 더 단순하고 자연스럽게 평행 한 프리미티브로 만드는 방법은 매우 흥미 롭습니다.

구문과 관련하여 ...이 문제를 해결하는 가장 좋은 방법은 샘플 프로그램을 작성하는 것입니다. 배열을 정렬하는 프로그램을 작성하거나 여러 서버를 동시에 핑 (ping)하고 어느 서버가 가장 빠르게 응답하는지보고하거나 병렬로 미로를 해결하려고 시도하십시오. 이 작업을 수행하는 동안 구문에서 누락 된 사항이 명확 해 지므로 추가 할 수 있습니다. 몇 가지를 추가 한 후에는 공통점이 있는지 물어보고, 그렇다면 여러 가지 용도로 사용할 수있는 더 간단한 방법을 찾을 수 있습니다.


4

과거에도 비슷한 프로젝트가 시도되었습니다. 아이디어를 전리하기 위해 고전을 읽는 것이 좋습니다. (모든 링크는 Wikipedia로 이동합니다)

  • Unity 이 언어는 병렬 프로그래밍을 가르치는 데 사용되었습니다. 실제로 구현되지 않았다고 생각합니다. 구문은 다소 비밀 스럽지만 기본적으로 알 수없는 순서로 실행되고 더 이상 할 일이 없을 때까지 반복적으로 실행되는 명령문 모음이 있습니다. 이것은 당신이 요구하는 것에 가장 가깝습니다.

  • Occam 이 언어는 실제로 사용하도록 설계되었지만 실제로는 사용되지 않습니다. 여기에 키워드 PAR이 있는데, 이는 명령문 목록이 병렬로 실행되어야 함을 의미합니다.

  • Erlang 또 다른 실제 언어. 이 회사는 통신 회사 Ericsson이 사용하며 다음과 같은 내용을 가지고 있습니다. 그들은 병렬 처리를 실용적이고 유용하게 만들기 위해 많은 노력을 기울였습니다.

  • 구글 GO 이것은 내가 가장 좋아하는 것입니다. 개념적으로 Erlang과 거의 동일하지만 구문이 우수하고 그 뒤에 Google의 가중치가 있습니다. 무엇이 잘못 될 수 있습니까?

나는 경고로 마무리하고 싶다 : 병렬 처리는 매우 어렵다. 현대 프로그램에서 대부분의 버그는 잘못된 결과입니다 . 정말로 가고 싶습니까?


내 목록에없는 언어에 대한 위반은 없습니다. 내 지식이 제한적일뿐입니다.
Stig Hemmer

3

가능하지만 모든 생각할 수있는 응용 프로그램의 99 % 이상에는 유용하지 않습니다. 논리는 전형적인 시퀀스 바운드이며 흐름입니다. 단계별로 문제에 대한 해결책에 도달하면 단계의 순서가 중요합니다. 대부분 한 단계의 출력이 다음 단계에 대해 입력되기 때문입니다.

소수의 경우 서로 독립적으로 수행 할 수있는 많은 작업이 있지만, 병렬로 실행하기 전에 순차적으로 설정하는 것이 일반적으로 저렴합니다.

따라서 원하는 프로그래밍 언어로 멀티 스레딩 기능을 사용하는 방법을 배우는 데 시간이 더 많이 걸릴 것이라고 생각합니다.


5
이것은 다른 질문에 대한 훌륭한 답변입니다. OP는 그러한 체계의 지혜에 대해 묻지 않고 단지 그 체계가 이루어질 수 있는지 여부와 "구문"이 어떻게 보이는지에 대해 묻고있다.
DepressedDaniel

9
그것을 요구하지 않는 사람들은 나의 지혜가 가장 필요하다. 누군가가 장바구니에서 언덕을 내려갈 수 있는지 물으면 "답니다. 바퀴에 기름칠을하세요!"가 아닙니다. "글쎄,하지만 ..."와 비슷할 것입니다.
Martin Maat

이전 EIAO 어셈블리 언어 명령어 인 Execute In Any Order를 상기 시킵니다. (그리고 어쨌든 그 키는 어디에 있습니까?)

@MartinMaat 아무도 재미를 위해 프로그래밍 언어를 작성하여 스스로를 죽일 수 없습니다
user253751

2

Clojure는 몇 가지 아이디어를 살펴볼 가치가 있습니다.

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

다음은 몇 가지 생각입니다. 독립적으로 수행 할 수있는 계산 단위를 호출하는 경우 : 1. 작업은 독립적이므로 동시에 실행할 수 있습니다. 2. 다른 작업에는 다른 리소스가 필요하고 실행하는 데 다른 시간이 걸립니다. 최대 처리량 4. 스케줄러 역할을 할 위치에있는 유일한 프로그램은 운영 체제입니다.

사과 웅대 한 중앙 파견과 같은 것은 그러한 스케줄러를 제공하려는 시도입니다.

위의 작업을 수행하는 책임은 반드시 프로그래밍 언어의 책임이 아님을 의미합니다.

두 번째 생각은 병렬 시스템 프로그래밍의 부담을 최대한 줄이는 것입니다. 이를 수행하는 유일한 방법은 프로그램에서 수행 할 작업에 대한 사양을 제거하는 것입니다. 프로그램은 수행 할 작업 만 지정하고 나머지는 자동으로 수행해야합니다.

위의 내용은 동적 언어와 적시에 컴파일하는 것이 좋습니다.


2

당신이 찾고있는 것을 암시 적 병렬 림이라고 부르며 Sun / Oracle 's Fortress 와 같은이 개념을 탐구 한 언어가 있습니다 . 무엇보다도 (잠재적으로) 루프를 병렬로 실행합니다.

불행히도, 그것은 중단 되었고 거기에 많은 죽은 링크가 있지만, 구글을 충분히 열심히 사용한다면 여전히 몇 개의 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
Fortress를 언급 한 것에 대해 +1 ... 나는 언어에 대한 아이디어를 매우 좋아했습니다. 그들이 개발이 중단되었다고 발표했을 때 정말 슬 was습니다 ...
Roland Tepp

2

프로그래밍 언어는 아니지만 VHDL을 살펴보십시오 . 디지털 회로를 설명하는 데 사용되며, 직렬로 지시하지 않는 한 자연스럽게 모든 것을 병렬로 수행합니다. 언어를 디자인하는 방법과 어떤 종류의 논리에 적합한 지에 대한 아이디어를 줄 수 있습니다.


0

이것은 C ++에서 매우 쉽게 시뮬레이션 할 수 있습니다. "모든"* 함수 호출이에 의해 구현되는지 확인하십시오 std::future. 반환 값을 처리하는 것은 단순히 .get()미래 를 호출 하여 수행됩니다 .

따라서 C ++로 컴파일하여 언어를 프로토 타입 할 수 있습니다. 또한 구문의 모양을 알려줍니다. 가장 큰 차이점은 입력 인수가 제공되는 콜 포인트를 반환 지점 (함수 출력이 사용되는)과 분리하는 것입니다.

(*) "모든 기능"이라고 말하지만 기능으로 간주되는 것은 사용자에게 달려 있습니다. 가 memset고유 또는 기능은? 정수 할당 또는 사용자 정의 유형 할당은 함수 호출입니까?


그리고 질문에 대한 답변을 충분히 길게 연기하면 대개 답변이 필요하지 않습니다. 이것이 "게으른 기존"이라고 생각합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.