Hi. I need little more help with Nim's async/await. I did two samples: for C# and Nim. C#:
using System;
using System.Threading.Tasks;
namespace AsyncSample
{
class MainClass
{
static bool ap1Done = false;
static bool ap2Done = false;
static int sum (int count)
{
int result = 0;
for (int i = 0; i < (count+1); i++)
result += i;
return result;
}
static Task<int> cbp1() { return Task.Run(() => { return sum (100000000); }); }
async static void ap1 () {
int i = await cbp1 ();
Console.WriteLine ("Async Result 1: {0}", i);
ap1Done = true;
}
static Task<int> cbp2() { return Task.Run(() => { return sum (10); }); }
async static void ap2 ()
{
int i = await cbp2 ();
Console.WriteLine ("Async Result 2: {0}", i);
ap2Done = true;
}
public static void Main (string[] args)
{
ap1 ();
ap2 ();
while (!ap1Done || !ap2Done)
System.Threading.Thread.Sleep (100);
}
}
}
result (don't look at value in Async Result 1, it's trash:) ):
Async Result 2: 55
Async Result 1: 987459712
Press any key to continue...
Nim:
import asyncdispatch
from os import sleep
var ap1Done = false
var ap2Done = false
proc sum (count: int): int =
result = 0
for i in 0..count: result += i
proc cbp1(): Future[int] =
var retFuture = newFuture[int]("cbp1")
retFuture.complete(sum(100000000))
return retFuture
proc ap1() {.async.} =
var i = await cbp1()
echo "Async Result 1: " & $i
ap1Done = true
proc cbp2(): Future[int] =
var retFuture = newFuture[int]("cbp2")
retFuture.complete(sum(10))
return retFuture
proc ap2() {.async.} =
var i = await cbp2()
echo "Async Result 2: " & $i
ap2Done = true
discard ap1()
discard ap2()
while not ap1Done or not ap2Done:
sleep(100)
result:
Async Result 1: 5000000050000000
Async Result 2: 55
How to compel this code to work asynchronously (without making a threads manually)?AFAIK, asyncdispatch is single threaded. What you want is spawn of threadpool
import threadpool
from os import sleep
proc sum (count: int): int =
result = 0
for i in 0..count: result += i
var
fut1 = spawn sum(100000000)
fut2 = spawn sum(10)
while not fut1.isReady and not fut2.isReady:
sleep(100)
echo "fut1: ", ^fut1
echo "fut2: ", ^fut2
compile with --threads:on option
Thanks for example. Yes, I saw that notice in manual (about singlethreaded). Think this code does same my C#-example:
import asyncdispatch, threadpool
from os import sleep
proc sum (count: int): int =
result = 0
for i in 0..count: result += i
proc ap1(): int =
result = sum(100000000)
echo "Async Result 1: " & $result
proc ap2(): int =
result = sum(10)
echo "Async Result 2: " & $result
var ap1Res = spawn ap1()
var ap2Res = spawn ap2()
while not ap1Res.isReady or not ap2Res.isReady:
sleep(100)
But this adds even more questions, what is reason the use of async/await :-| Probably I must re-read the manualBut this adds even more questions, what is reason the use of async/await
For IO operations efficiency and (maybe) safety, system threads don't scale well, it becomes more notorious when you need to share memory between threads. You maybe try to resort to mutex or atomic, but it becomes much more complex as your program grows.
You maybe try to resort to mutex or atomic, but it becomes much more complex as your program grows.
Yes, it is. But Nim's async/await really isn't do asyncronous code and doesn't perform operations in parallel, right?
But Nim's async/await really isn't do asyncronous code and doesn't perform operations in parallel, right?
Yes, and no. Yes because you code like just you code a single thread. IO operations done in kernel level instead of user level. Basically while a part of your code waiting for IO operations finished, your program still able to operate without waiting the code that do I/O.
I suggest you read this article http://www.kegel.com/c10k.html not directly related on what you want but it's explained there.
Yes. If you want to explore more, try build a server which handle several hundreds connections using spawn.
For realistic example or benchmark, do it especially each spawned handler write/read something from database, you'll find an interesting result ;)