Flutter Dart: How can we achieve multithreading like python or java in dart

17,456

Solution 1

Dart/Flutter is single threaded and not possible to share global variable. As each isolate has its own memory,space and everything. To make it work like multi threaded you have to use isolates and the communication will be used through ports by sending message to one another. If you not want to use Future you can use isolates.

Read

  1. https://medium.com/flutter-community/flutter-threading-5c3a7b0c065f

  2. https://www.tutorialspoint.com/dart_programming/dart_programming_concurrency.htm

  3. https://pub.dev/packages/threading

Solution 2

You can't, threads in multithreading usually run in a shared memory space, while processes in multiprocessing run in separate memory spaces. Check this.

Flutter has isolates where each isolate has its own private space, you can think of it as multiprocessing, which is achieved in python using the multiprocessing package (not threading). In Java, multiprocessing exists but is not usually used for concurrency.

The dart documentation mentions that isolates are similar to threads (not that they are threads), and they can achieve concurrency in a simpler way as locking is not required.

Solution 3

flutter has a top level function compute, it is a sintax sugar for isolates, can be all you need in some cases

import 'package:flutter/foundation.dart';

Future<int> sum(List<int> params) async {
  return params.reduce((a, b) => a + b);
}

void main() async {
  final respFromOtherIsolate = await compute(sum,[1,2,5]);
  print('resp: $respFromOtherIsolate');
}

see more:

Share:
17,456

Related videos on Youtube

dinesh.rajbhar
Author by

dinesh.rajbhar

Updated on May 21, 2022

Comments

  • dinesh.rajbhar
    dinesh.rajbhar almost 2 years

    I want to achieve Thread A and Thread B runs in parallel and sharing global variable.

    Below is the code written in python. Same I want to do in Dart (I don't want to use future await because it is waiting for other thread to finish or got to wait.)

    Case Variable:

    val 
    ai ( a increment )
    ad ( a decrement )
    af ( a fail ) 
    bi ( b increment )
    bd ( b decrement )
    bf ( b fail ) // when unable to get log
    

    I have two function A() and B() and global variable val. Both function randomly increment or decrements global variable val. and based on that i am calculating error and printing to console (written in pr function)


    O.val (Original val received at time of executing)
    C.val (Calculated val)
    err= ai - ad + bi - bd - val
    
    
    _/+    O.val C.val    ai     ad  ai-ad      bi    bd  bi-ad    err
    
    A- |     0    -1 |     0     1    -1 |      0     0     0 |    0
    B+ |    -1     0 |     0     1    -1 |      1     0     1 |    0
    A- |     0    -1 |     0     2    -2 |      1     0     1 |    0
    B+ |    -1     0 |     0     2    -2 |      2     0     2 |    0
    A- |     0    -1 |     0     3    -3 |      2     0     2 |    0
    B- |    -1    -2 |     0     3    -3 |      2     1     1 |    0
    
    

    Python side:

    ##############
    # Python Code
    # ############
    
    import thread;
    import time;
    
    def lhrand(lo, hi): import random; return lo + int (random.random() * (hi - lo));
    
    mutex= thread.allocate_lock();
    val= 0;
    ai= ad= af= 0;
    bi= bd= bf= 0;
    
    def pr(id, sign, _val):
        global val, ai, ad, af, bi, bd, bf;
        return "%s%s | %5d %5d | %5d %5d %5d |  %5d %5d %5d | %4d" % (id, sign, _val, val, ai, ad, af, bi, bd, bf, ai - ad + bi - bd - val);
    
    def A(id):
       global val, ai, ad;
       for j in range(0, 10000):
           r= lhrand(0, 2);
           s= "-+"[r];
           w= [-1, 1][r];
           line= None;
           if mutex:
               if mutex.acquire():
                   o= val;
                   if r == 0: ad+= 1; else: ai+= 1;
                   val= val + w;
                   pr(id, "-" if r == 0 else "+", o);
                   mutex.release();
                   line= pr(id, s, o);
       print("%s over" % id);
       return 0;
    
    
    def B(id):
       global val, bi, bd;
       for j in range(0, 10000):
           if mutex and mutex.acquire():
               r= lhrand(0, 2);
               o= x= val;
               if r == 0: bd+= 1;
               if r == 1: bi+= 1;
               x= x - 1 if r == 0 else x + 1;
               val= x;
               pr(id, "-" if r == 0 else "+", o);
               mutex.release();
       print("%s over" % id);
       return 0;
    
    if __name__ == "__main__":
        x= thread.start_new_thread(A, ("A",))
        y= thread.start_new_thread(B, ("B",))
        time.sleep(5.0);
        pr("X", ".", val);
    
    exit(0);
    
    

    Dart side:

    /////////////
    //  Dart Code
    /////////////
    
    import "dart:async";
    import "dart:math";
    import "package:threading/threading.dart";
    import "package:sprintf/sprintf.dart";
    
    int val= 0;
    int ai= 0, ad= 0, bi=0, bd= 0;
    int num= 10000;
    
    Lock _lock = new Lock();
    
    var isLockEnable= true;
    
    Random random= new Random();
    int lhrand(lo, hi)
            {
            return lo + random.nextInt(hi - lo);
            }
    
    int pr(id, sign, _val)
            {
            var s= sprintf("%s%s | %5d %5d | %5d %5d %5d |  %5d %5d %5d | %4d", [id, sign, _val, val, ai, ad, ai - ad, bi, bd, bi - bd, ai - ad + bi - bd - val]);
            print(s);
            return 0;
            }
    Future A() async
            {
            int r, o, x;
            var id= "A";
            for(var j in Iterable<int>.generate(num).toList())
            {
            try
                    {
                    if(isLockEnable)
                            {
                            await _lock.acquire();
                            }
                    o= await Future((){ return val; });
                    x= val;
                    r= lhrand(0, 2);
                    x= val;
                    if(r == 0) { ad++; }
                    if(r == 1) { ai++; }
                    x= (r == 0) ? x - 1 : x + 1;
                    val= x;
                    pr(id, (r == 0) ? "-" : "+", o);
                    if(isLockEnable)
                            {
                            await _lock.release();
                            }
                    }
            catch(e)
                    {
                    print("A failed to get lock.");
                    }
            }
            print("$id over");
            }
    Future B() async
            {
            int r, o, x;
            var id= "B";
            for(var j in Iterable<int>.generate(num).toList())
                    {
                    try
                            {
                            if(isLockEnable)
                                    {
                                    await _lock.acquire();
                                    }
                            o= await Future((){ return val; });
                            r= lhrand(0, 2);
                            x= val;
                            if(r == 0) { bd++; }
                            if(r == 1) { bi++; }
                            x= (r == 0) ? x - 1 : x + 1;
                            val= x;
                            pr(id, (r == 0) ? "-" : "+", o);
                            if(isLockEnable)
                                    {
                                    await _lock.release();
                                    }
                            }
                    catch(e)
                            {
                            print("B failed to get lock.");
                            }
                    }
            print("$id over");
            }
    Future main() async
            {
            var AT= new Thread(A);
            print("AT : " + AT.hashCode.toString());
            var BT= new Thread(B);
            print("BT : " + BT.hashCode.toString());
            AT.start();
            BT.start();
            return 0;
            }
    
    
    • RonTLV
      RonTLV over 3 years
      Future / await / async
    • Volodymyr Bobyr
      Volodymyr Bobyr over 3 years
      The thread library in python is not multithreaded. It's a single thread that's managed by Python's GIL. You can achieve similar behavior with futures, as @RonTLV said, but it's all still on a single thread.
  • dinesh.rajbhar
    dinesh.rajbhar about 4 years
    Thanks Dev. I already gone through the link you shared. I want to know whether it actually supported multi-threading like python or java and Is dart isolate is only solution to achieve that.
  • Dev
    Dev about 4 years
    NO Dart doesnt support multithreading like java /python. But you can use multiple isolates to imitate this requirement.
  • kodmanyagha
    kodmanyagha over 3 years
    please can you explain about that: communication will be used through ports? Thanks.
  • Dev
    Dev over 3 years
  • Philipos D.
    Philipos D. almost 3 years
    You can also check this video from the Flutter team regarding Isolates and multithreading in Flutter