Policy change. Edit privileges will now require email addresses to be confirmed. (Details) --Michael Mol 14:53, 14 March 2012 (UTC)

Concurrent computing

From Rosetta Code
Jump to: navigation, search
Task
Concurrent computing
You are encouraged to solve this task according to the task description, using any language you may know.
Using either native language concurrency syntax or freely available libraries write a program to display the strings "Enjoy" "Rosetta" "Code", one string per line, in random order. Concurrency syntax must use threads, tasks, co-routines, or whatever concurrency is called in your language.


Contents

[edit] Ada

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
 
procedure Concurrent_Hello is
task type Writer (Message : not null access String);
task body Writer is
Seed : Generator;
begin
Reset (Seed); -- This is time-dependent, see ARM A.5.2
delay Duration (Random (Seed));
Put_Line (Message.all);
end Writer;
 
S1 : aliased String := "Enjoy";
S2 : aliased String := "Rosetta";
S3 : aliased String := "Code";
T1 : Writer (S1'Access);
T2 : Writer (S2'Access);
T3 : Writer (S3'Access);
begin
null;
end Concurrent_Hello;

Note that random generator object is local to each task. It cannot be accessed concurrently without mutual exclusion. In order to get different initial states of local generators Reset is called (see ARM A.5.2).

[edit] ALGOL 68

main:(
PROC echo = (STRING string)VOID:
printf(($gl$,string));
PAR(
echo("Enjoy"),
echo("Rosetta"),
echo("Code")
)
)

[edit] C

Works with: POSIX
Library: pthread
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
 
pthread_mutex_t condm = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int bang = 0;
 
#define WAITBANG() do { \
pthread_mutex_lock(&condm); \
while( bang == 0 ) \
{ \
pthread_cond_wait(&cond, &condm); \
} \
pthread_mutex_unlock(&condm); } while(0);\

void *t_enjoy(void *p)
{
WAITBANG();
printf("Enjoy\n");
pthread_exit(0);
}
 
void *t_rosetta(void *p)
{
WAITBANG();
printf("Rosetta\n");
pthread_exit(0);
}
 
void *t_code(void *p)
{
WAITBANG();
printf("Code\n");
pthread_exit(0);
}
 
typedef void *(*threadfunc)(void *);
int main()
{
int i;
pthread_t a[3];
threadfunc p[3] = {t_enjoy, t_rosetta, t_code};
 
for(i=0;i<3;i++)
{
pthread_create(&a[i], NULL, p[i], NULL);
}
sleep(1);
bang = 1;
pthread_cond_broadcast(&cond);
for(i=0;i<3;i++)
{
pthread_join(a[i], NULL);
}
}

Note: since threads are created one after another, it is likely that the execution of their code follows the order of creation. To make this less evident, I've added the bang idea using condition: the thread really executes their code once the gun bang is heard. Nonetheless, I still obtain the same order of creation (Enjoy, Rosetta, Code), and maybe it is because of the order locks are acquired. The only way to obtain randomness seems to be to add random wait in each thread (or wait for special cpu load condition)

[edit] OpenMP

Compile with gcc -std=c99 -fopenmp:

#include <stdio.h>
#include <omp.h>
 
int main()
{
char *str[] = { "Enjoy", "Rosetta", "Code" };
#pragma omp parallel for num_threads(3)
for (int i = 0; i < 3; i++)
printf("%s\n", str[i]);
}

[edit] C++

#include <iostream>
#include <ppl.h> // MSVC++
 
void a(void) { std::cout << "Eat\n"; }
void b(void) { std::cout << "At\n"; }
void c(void) { std::cout << "Joe's\n"; }
 
int main()
{
// function pointers
Concurrency::parallel_invoke(&a, &b, &c);
 
// C++11 lambda functions
Concurrency::parallel_invoke(
[]{ std::cout << "Enjoy\n"; },
[]{ std::cout << "Rosetta\n"; },
[]{ std::cout << "Code\n"; }
);
return 0;
}

Output:

Joe's
Eat
At
Enjoy
Code
Rosetta

[edit] C#

 
static Random tRand = new Random();
 
static void Main(string[] args)
{
Thread t = new Thread(new ParameterizedThreadStart(WriteText));
t.Start("Enjoy");
 
t = new Thread(new ParameterizedThreadStart(WriteText));
t.Start("Rosetta");
 
t = new Thread(new ParameterizedThreadStart(WriteText));
t.Start("Code");
 
Console.ReadLine();
}
 
private static void WriteText(object p)
{
Thread.Sleep(tRand.Next(1000, 4000));
Console.WriteLine(p);
}
 

An example result:

Enjoy
Code
Rosetta

[edit] Clojure

A simple way to obtain concurrency is using the future function, which evaluates its body on a separate thread.

 
(doseq [text ["Enjoy" "Rosetta" "Code"]]
(future (println text)))
 

[edit] CoffeeScript

Works with: node.js v0.4

Javascript, which CS compiles to, is single-threaded. This approach launches multiple process to achieve concurrency on node.js:

exec = require('child_process').exec
 
for word in ["Enjoy", "Rosetta", "Code"]
exec "echo #{word}", (err, stdout) ->
console.log stdout
 

[edit] Common Lisp

Concurrency and threads are not part of the Common Lisp standard. However, most implementations provide some interface for concurrency. Bordeaux Threads, used here, provides a compatibility layer for many implementations. (Binding out to *standard-output* before threads are created is needed as each thread gets its own binding for *standard-output*.)

(defun concurrency-example (&optional (out *standard-output*))
(let ((lock (bordeaux-threads:make-lock)))
(flet ((writer (string)
#'(lambda ()
(bordeaux-threads:acquire-lock lock t)
(write-line string out)
(bordeaux-threads:release-lock lock))))
(bordeaux-threads:make-thread (writer "Enjoy"))
(bordeaux-threads:make-thread (writer "Rosetta"))
(bordeaux-threads:make-thread (writer "Code")))))

[edit] D

Library: Tango
import tango.core.Thread;
import tango.io.Console;
import tango.math.Random;
 
void main() {
(new Thread( { Thread.sleep(Random.shared.next(1000) / 1000.0); Cout("Enjoy").newline; } )).start;
(new Thread( { Thread.sleep(Random.shared.next(1000) / 1000.0); Cout("Rosetta").newline; } )).start;
(new Thread( { Thread.sleep(Random.shared.next(1000) / 1000.0); Cout("Code").newline; } )).start;
}

[edit] Delphi

program ConcurrentComputing;
 
{$APPTYPE CONSOLE}
 
uses SysUtils, Classes, Windows;
 
type
TRandomThread = class(TThread)
private
FString: string;
protected
procedure Execute; override;
public
constructor Create(const aString: string); overload;
end;
 
constructor TRandomThread.Create(const aString: string);
begin
inherited Create(False);
FreeOnTerminate := True;
FString := aString;
end;
 
procedure TRandomThread.Execute;
begin
Sleep(Random(5) * 100);
Writeln(FString);
end;
 
var
lThreadArray: Array[0..2] of THandle;
begin
Randomize;
lThreadArray[0] := TRandomThread.Create('Enjoy').Handle;
lThreadArray[1] := TRandomThread.Create('Rosetta').Handle;
lThreadArray[2] := TRandomThread.Create('Stone').Handle;
 
WaitForMultipleObjects(Length(lThreadArray), @lThreadArray, True, INFINITE);
end.

[edit] dodo0

fun parprint -> text, return
(
fork() -> return, throw
println(text, return)
| x
return()
)
| parprint
 
parprint("Enjoy") ->
parprint("Rosetta") ->
parprint("Code") ->
 
exit()

[edit] E

def base := timer.now()
for string in ["Enjoy", "Rosetta", "Code"] {
timer <- whenPast(base + entropy.nextInt(1000), fn { println(string) })
}

Nondeterminism from preemptive concurrency rather than a random number generator:

def seedVat := <import:org.erights.e.elang.interp.seedVatAuthor>(<unsafe>)
for string in ["Enjoy", "Rosetta", "Code"] {
seedVat <- (`
fn string {
println(string)
currentVat <- orderlyShutdown("done")
}
`
) <- get(0) <- (string)
}

[edit] Erlang

hw.erl

-module(hw).
-export([start/0]).
 
start() ->
[ spawn(fun() -> say(self(), X) end) || X <- ['Enjoy', 'Rosetta', 'Code'] ],
wait(2),
ok.
 
say(Pid,Str) ->
io:fwrite("~s~n",[Str]),
Pid ! done.
 
wait(N) ->
receive
done -> case N of
0 -> 0;
_N -> wait(N-1)
end
end.

running it

|erlc hw.erl
|erl -run hw start -run init stop -noshell

[edit] Euphoria

procedure echo(sequence s)
puts(1,s)
puts(1,'\n')
end procedure
 
atom task1,task2,task3
 
task1 = task_create(routine_id("echo"),{"Enjoy"})
task_schedule(task1,1)
 
task2 = task_create(routine_id("echo"),{"Rosetta"})
task_schedule(task2,1)
 
task3 = task_create(routine_id("echo"),{"Code"})
task_schedule(task3,1)
 
task_yield()

Output:

Code
Rosetta
Enjoy

[edit] F#

We define a parallel version of Seq.iter by using asynchronous workflows:

module Seq =     
let piter f xs =
seq { for x in xs -> async { f x } }
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
 
let main() = Seq.piter
(System.Console.WriteLine:string->unit)
["Enjoy"; "Rosetta"; "Code";]
 
main()

With version 4 of the .NET framework and F# PowerPack 2.0 installed, it is possible to use the predefined PSeq.iter instead.

[edit] Factor

USE: concurrency.combinators
 
{ "Enjoy" "Rosetta" "Code" } [ print ] parallel-each

[edit] Forth

Works with: gforth version 0.6.2

Many Forth implementations come with a simple cooperative task scheduler. Typically each task blocks on I/O or explicit use of the pause word. There is also a class of variables called "user" variables which contain task-specific data, such as the current base and stack pointers.

require tasker.fs
require random.fs
 
: task ( str len -- )
64 NewTask 2 swap pass
( str len -- )
10 0 do
100 random ms
pause 2dup cr type
loop 2drop ;
 
: main
s" Enjoy" task
s" Rosetta" task
s" Code" task
begin pause single-tasking? until ;
main

[edit] Fortran

Fortran doesn't have threads but there are several compilers that support OpenMP, e.g. gfortran and Intel. The following code has been tested with thw Intel 11.1 compiler on WinXP.

program concurrency
implicit none
character(len=*), parameter :: str1 = 'Enjoy'
character(len=*), parameter :: str2 = 'Rosetta'
character(len=*), parameter :: str3 = 'Code'
integer :: i
real :: h
real, parameter :: one_third = 1.0e0/3
real, parameter :: two_thirds = 2.0e0/3
 
interface
integer function omp_get_thread_num
end function omp_get_thread_num
end interface
interface
integer function omp_get_num_threads
end function omp_get_num_threads
end interface
 
! Use OpenMP to create a team of threads
!$omp parallel do private(i,h)
do i=1,20
! First time through the master thread output the number of threads
! in the team
if (omp_get_thread_num() == 0 .and. i == 1) then
write(*,'(a,i0,a)') 'Using ',omp_get_num_threads(),' threads'
end if
 
! Randomize the order
call random_number(h)
 
!$omp critical
if (h < one_third) then
write(*,'(a)') str1
else if (h < two_thirds) then
write(*,'(a)') str2
else
write(*,'(a)') str3
end if
!$omp end critical
end do
!$omp end parallel do
 
end program concurrency

[edit] Go

[edit] Channel

Simplest and most direct solution: Start three goroutines, give each one a word. Each sleeps, then returns the word on a channel. The main goroutine prints words as they return. The print loop represents a checkpoint--main doesn't exit until all words have returned and been printed.

package main
 
import (
"fmt"
"math/rand"
"time"
)
 
func main() {
words := []string{"Enjoy", "Rosetta", "Code"}
rand.Seed(time.Now().UnixNano())
q := make(chan string)
for _, w := range words {
go func(w string) {
time.Sleep(time.Duration(rand.Int63n(1e9)))
q <- w
}(w)
}
for i := 0; i < len(words); i++ {
fmt.Println(<-q)
}
}

[edit] Afterfunc

time.Afterfunc combines the sleep and the goroutine start. log.Println serializes output in the case goroutines attempt to print concurrently. sync.WaitGroup is used directly as a checkpoint.

package main
 
import (
"log"
"math/rand"
"os"
"sync"
"time"
)
 
func main() {
words := []string{"Enjoy", "Rosetta", "Code"}
rand.Seed(time.Now().UnixNano())
l := log.New(os.Stdout, "", 0)
var q sync.WaitGroup
q.Add(len(words))
for _, w := range words {
w := w
time.AfterFunc(time.Duration(rand.Int63n(1e9)), func() {
l.Println(w)
q.Done()
})
}
q.Wait()
}

[edit] Select

This solution might stretch the intent of the task a bit. It is concurrent but not parallel. Also it doesn't sleep and doesn't call the random number generator explicity. It works because the select statement is specified to make a "pseudo-random fair choice" among multiple channel operations.

package main
 
import "fmt"
 
func main() {
w1 := make(chan bool, 1)
w2 := make(chan bool, 1)
w3 := make(chan bool, 1)
for i := 0; i < 3; i++ {
w1 <- true
w2 <- true
w3 <- true
fmt.Println()
for i := 0; i < 3; i++ {
select {
case <-w1:
fmt.Println("Enjoy")
case <-w2:
fmt.Println("Rosetta")
case <-w3:
fmt.Println("Code")
}
}
}
}

Output:

Code
Rosetta
Enjoy

Enjoy
Rosetta
Code

Rosetta
Enjoy
Code

[edit] Groovy

'Enjoy Rosetta Code'.tokenize().collect { w ->
Thread.start {
Thread.sleep(1000 * Math.random() as int)
println w
}
}.each { it.join() }

[edit] Haskell

Note how the map treats the list of processes just like any other data.

import Control.Concurrent
 
main = mapM_ forkIO [process1, process2, process3] where
process1 = putStrLn "Enjoy"
process2 = putStrLn "Rosetta"
process3 = putStrLn "Code"

[edit] Icon and Unicon

The following code uses features exclusive to Unicon

procedure main()
L:=[ create write("Enjoy"), create write("Rosetta"), create write("Code")]
every thread(!L)
every join(!L)
end

[edit] J

Example:

   smoutput&>({~?~@#);:'Enjoy Rosetta Code'
Rosetta
Code
Enjoy

NOTES AND CAUTIONS:

1) While J's syntax and semantics is highly parallel, it is a deterministic sort of parallelism (analogous to the design of modern GPUs) and not the stochastic parallelism which is implied in this task specification (and which is usually obtained by timeslicing threads of control). The randomness implemented here is orthogonal to the parallelism in the display (and you could remove smoutput& without altering the appearence, in this trivial example).

2) The current working beta of J (and the past implementations) do not implement hardware based concurrency. This is partially an economic issue (since all of the current and past language implementations have been distributed for free, with terms which allow free distribution), and partially a hardware maturity issue (historically, most CPU multi-core development has been optimized for stochastic parallelism with minimal cheap support for large scale deterministic parallelism and GPUs have not been capable of supporting the kind of generality needed by J).

This state of affairs is likely to change, eventually (most likely this will be after greater than factor of 2 speedups from hardware parallelism are available for the J users in cases which are common and important enough to support the implementation). But, for now, J's parallelism is entirely conceptual.

[edit] Java

Uses CyclicBarrier to force all threads to wait until they're at the same point before executing the println, increasing the odds they'll print in a different order (otherwise, while the they may be executing in parallel, the threads are started sequentially and with such a short run-time, will usually output sequentially as well).

import java.util.concurrent.CyclicBarrier;
 
public class Threads
{
public static class DelayedMessagePrinter implements Runnable
{
private CyclicBarrier barrier;
private String msg;
 
public DelayedMessagePrinter(CyclicBarrier barrier, String msg)
{
this.barrier = barrier;
this.msg = msg;
}
 
public void run()
{
try
{ barrier.await(); }
catch (Exception e)
{ }
System.out.println(msg);
}
}
 
public static void main(String[] args)
{
CyclicBarrier barrier = new CyclicBarrier(3);
new Thread(new DelayedMessagePrinter(barrier, "Enjoy")).start();
new Thread(new DelayedMessagePrinter(barrier, "Rosetta")).start();
new Thread(new DelayedMessagePrinter(barrier, "Code")).start();
}
}

[edit] JavaScript

Javascript is single-threaded, so there is no real concurrency. This will print the words from random timers:

 
["Enjoy", "Rosetta", "Code"].forEach(function(word){
setTimeout(function(){ console.log(word) }, Math.random()*1000);
})
 

See the Concurrent_computing#CoffeeScript example for a multi-process approach.

JavaScript now enjoys access to a concurrency library thanks to Web Workers. This first code should be in the concurrent_worker.js file.

 
var onmessage = function(event) {
setTimeout(function() {
postMessage(event.data);
},Math.random()*1000);
};
 

This second block creates the workers, sends them a message and then cleans up the output. All output is placed into an element with the id "result".

 
var words = ["Enjoy","Rosetta","Code"];
var workers = [];
var worker_count = 0;
 
for(var i = 0; i < words.length; i++) {
workers[i] = new Worker("concurrent_worker.js");
workers[i].onmessage = accumulate;
workers[i].postMessage({"id": i, "word": words[i]});
}
 
function accumulate(event) {
id = event.data.id;
word = event.data.word;
console.log(word));
// Cleanup - kill the worker
workers[id].terminate();
}
 

[edit] Logtalk

:- object(concurrency).
 
:- initialization(output).
 
output :-
threaded((
write('Enjoy'),
write('Rosetta'),
write('Code')
)).
 
:- end_object.

[edit] Lua

co = {}
co[1] = coroutine.create( function() print "Enjoy" end )
co[2] = coroutine.create( function() print "Rosetta" end )
co[3] = coroutine.create( function() print "Code" end )
 
math.randomseed( os.time() )
h = {}
i = 0
repeat
j = math.random(3)
if h[j] == nil then
coroutine.resume( co[j] )
h[j] = true
i = i + 1
end
until i == 3

[edit] Mathematica

Parallelization requires Mathematica 7 or later

ParallelDo[
Pause[RandomReal[]];
Print[s],
{s, {"Enjoy", "Rosetta", "Code"}}
]

[edit] Mercury

:- module concurrent_computing.
:- interface.
 
:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.
 
:- implementation.
:- import_module thread.
 
main(!IO) :-
spawn(io.print_cc("Enjoy\n"), !IO),
spawn(io.print_cc("Rosetta\n"), !IO),
spawn(io.print_cc("Code\n"), !IO).

[edit] Objeck

 
bundle Default {
class MyThread from Thread {
New(name : String) {
Parent(name);
}
 
method : public : Run(param : Base) ~ Nil {
string := param->As(String);
string->PrintLine();
}
}
 
class Concurrent {
New() {
}
 
function : Main(args : System.String[]) ~ Nil {
t0 := MyThread->New("t0");
t1 := MyThread->New("t1");
t2 := MyThread->New("t2");
 
t0->Execute("Enjoy"->As(Base));
t1->Execute("Rosetta"->As(Base));
t2->Execute("Code"->As(Base));
}
}
}
 

[edit] OCaml

#directory "+threads"
#load "unix.cma"
#load "threads.cma"
let sleepy_print msg =
Unix.sleep ( Random.int 4 );
print_endline msg
let threads = List.map ( Thread.create sleepy_print ) ["Enjoy"; "Rosetta"; "Code"];;
let () = List.iter ( Thread.join ) threads;;

[edit] Oz

The randomness comes from the unpredictability of thread scheduling (this is how I understand this exercise).

for Msg in ["Enjoy" "Rosetta" "Code"] do
thread
{System.showInfo Msg}
end
end

[edit] PARI/GP

This is a PARI implementation which uses fork() internally. Note that the C solutions can be used instead if desired; this program demonstrates the native PARI capabilities instead.

For serious concurrency, see Appendix B of the User's Guide to the PARI Library which discusses a solution using tls on pthreads. (There are nontrivial issues with using PARI in this environment, do not attempt to blindly implement a C solution.)

void
foo()
{
if (pari_daemon()) {
// Original
if (pari_daemon()) {
// Original
pari_printf("Enjoy\n");
} else {
// Daemon #2
pari_printf("Code\n");
}
} else {
// Daemon #1
pari_printf("Rosetta\n");
}
}

See also Bill Allombert's slides on parallel programming in GP.

[edit] Perl

use threads;
use Time::HiRes qw(sleep);
 
$_->join for map {
threads->create(sub {
sleep rand;
print shift, "\n";
}, $_)
} qw(Enjoy Rosetta Code);
Or using coroutines provided by
Library: Coro
use feature qw( say );
use Coro;
use Coro::Timer qw( sleep );
 
$_->join for map {
async {
sleep rand;
say @_;
} $_
} qw( Enjoy Rosetta Code );
 

[edit] Perl 6

Works with: pugs

Hyper-operators are unordered:

my @words = <Enjoy Rosetta Code>;
@wordsยป.say

Output:

Rosetta
Code
Enjoy

[edit] PicoLisp

[edit] Using background tasks

(for (N . Str) '("Enjoy" "Rosetta" "Code")
(task (- N) (rand 1000 4000) # Random start time 1 .. 4 sec
Str Str # Closure with string value
(println Str) # Task body: Print the string
(task @) ) ) # and stop the task

[edit] Using child processes

(for Str '("Enjoy" "Rosetta" "Code")
(let N (rand 1000 4000) # Randomize
(unless (fork) # Create child process
(wait N) # Wait 1 .. 4 sec
(println Str) # Print string
(bye) ) ) ) # Terminate child process

[edit] Pike

Using POSIX threads:

int main() {
// Start threads and wait for them to finish
({
Thread.Thread(write, "Enjoy\n"),
Thread.Thread(write, "Rosetta\n"),
Thread.Thread(write, "Code\n")
})->wait();
 
// Exit program
exit(0);
}

Output:

Enjoy
Rosetta
Code

Using Pike's backend:

int main(int argc, array argv)
{
call_out(write, random(1.0), "Enjoy\n");
call_out(write, random(1.0), "Rosetta\n");
call_out(write, random(1.0), "Code\n");
call_out(exit, 1, 0);
return -1; // return -1 starts the backend which makes Pike run until exit() is called.
}

Output:

Rosetta
Code
Enjoy

[edit] PureBasic

Global mutex = CreateMutex()
 
Procedure Printer(*str$)
LockMutex(mutex)
PrintN(*str$)
UnlockMutex(mutex)
EndProcedure
 
If OpenConsole()
LockMutex(mutex)
thread1 = CreateThread(@Printer(), @"Enjoy")
thread2 = CreateThread(@Printer(), @"Rosetta")
thread3 = CreateThread(@Printer(), @"Code")
UnlockMutex(mutex)
 
WaitThread(thread1)
WaitThread(thread2)
WaitThread(thread3)
 
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Input()
 
CloseConsole()
EndIf
 
FreeMutex(mutex)

[edit] Python

Works with: Python version 3.2

Using the new to Python 3.2 concurrent.futures library and choosing to use processes over threads; the example will use up to as many processes as your machine has cores. This doesn't however guarantee an order of sub-process results.

Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win 32
Type "help", "copyright", "credits" or "license" for more information.
>>> from concurrent import futures
>>> with futures.ProcessPoolExecutor() as executor:
... _ = list(executor.map(print, 'Enjoy Rosetta Code'.split()))
...
Enjoy
Rosetta
Code
>>>
Works with: Python version 2.5
import threading
import random
 
def echo(text):
print(text)
 
threading.Timer(random.random(), echo, ("Enjoy",)).start()
threading.Timer(random.random(), echo, ("Rosetta",)).start()
threading.Timer(random.random(), echo, ("Code",)).start()

Or, by using a for loop to start one thread per list entry, where our list is our set of source strings:

import threading
import random
 
def echo(text):
print(text)
 
for text in ["Enjoy", "Rosetta", "Code"]:
threading.Timer(random.random(), echo, (text,)).start()

[edit] threading.Thread

import random, sys, time
import threading
 
lock = threading.Lock()
 
def echo(s):
time.sleep(1e-2*random.random())
# use `.write()` with lock due to `print` prints empty lines occasionally
with lock:
sys.stdout.write(s)
sys.stdout.write('\n')
 
for line in 'Enjoy Rosetta Code'.split():
threading.Thread(target=echo, args=(line,)).start()

[edit] multiprocessing

Works with: Python version 2.6
from __future__ import print_function
from multiprocessing import Pool
 
def main():
p = Pool()
p.map(print, 'Enjoy Rosetta Code'.split())
 
if __name__=="__main__":
main()

[edit] twisted

import random
from twisted.internet import reactor, task, defer
from twisted.python.util import println
 
delay = lambda: 1e-4*random.random()
d = defer.DeferredList([task.deferLater(reactor, delay(), println, line)
for line in 'Enjoy Rosetta Code'.split()])
d.addBoth(lambda _: reactor.stop())
reactor.run()

[edit] gevent

from __future__ import print_function
import random
import gevent
 
delay = lambda: 1e-4*random.random()
gevent.joinall([gevent.spawn_later(delay(), print, line)
for line in 'Enjoy Rosetta Code'.split()])

[edit] Raven

[ 'Enjoy' 'Rosetta' 'Code' ] as $words
 
thread talker
$words pop "%s\n"
repeat dup print
500 choose ms
 
talker as a
talker as b
talker as c

[edit] Rhope

Works with: Rhope version alpha 1
Main(0,0)
|:
Print["Enjoy"]
Print["Rosetta"]
Print["Code"]
:|

In Rhope, expressions with no shared dependencies run in parallel by default.

[edit] Ruby

%w{Enjoy Rosetta Code}.map do |x|
Thread.new do
sleep rand
puts x
end
end.each do |t|
t.join
end

[edit] Scala

import scala.actors.Futures
List("Enjoy", "Rosetta", "Code").map { x =>
Futures.future {
Thread.sleep((Math.random * 1000).toInt)
println(x)
}
}.foreach(_())

[edit] Scheme

(parallel-execute (lambda () (print "Enjoy"))
(lambda () (print "Rosetta"))
(lambda () (print "Code")))

[edit] Tcl

Assuming that "random" means that we really want the words to appear in random (rather then "undefined" or "arbitrary") order:

after [expr int(1000*rand())] {puts "Enjoy"}
after [expr int(1000*rand())] {puts "Rosetta"}
after [expr int(1000*rand())] {puts "Code"}

will execute each line after a randomly chosen number (0...1000) of milliseconds.

A step towards "undefined" would be to use after idle, which is Tcl for "do this whenever you get around to it". Thus:

after idle {puts "Enjoy"}
after idle {puts "Rosetta"}
after idle {puts "Code"}

(While no particular order is guaranteed by the Tcl spec, the current implementations will all execute these in the order in which they were added to the idle queue).

It's also possible to use threads for this. Here we do this with the built-in thread-pool support:

package require Thread
set pool [tpool::create -initcmd {
proc delayPrint msg {
after [expr int(1000*rand())]
puts $msg
}
}]
tpool::post -detached $pool [list delayPrint "Enjoy"]
tpool::post -detached $pool [list delayPrint "Rosetta"]
tpool::post -detached $pool [list delayPrint "Code"]
tpool::release $pool
after 1200 ;# Give threads time to do their work
exit

[edit] UnixPipes

(echo "Enjoy" & echo "Rosetta"& echo "Code"&)

[edit] Visual Basic .NET

Imports System.Threading
 
Module Module1
Public rnd As New Random
 
Sub Main()
Dim t1 As New Thread(AddressOf Foo)
Dim t2 As New Thread(AddressOf Foo)
Dim t3 As New Thread(AddressOf Foo)
 
t1.Start("Enjoy")
t2.Start("Rosetta")
t3.Start("Code")
 
t1.Join()
t2.Join()
t3.Join()
 
End Sub
 
Sub Foo(ByVal state As Object)
Thread.Sleep(rnd.Next(1000))
Console.WriteLine(state)
End Sub
 
End Module
Personal tools
Namespaces
Variants
Actions
Community/News
Browse wiki
Misc
Toolbox