threading 0.0.10

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 82

threading

Threading is an implementation of the cooperative, non-preemptive multitasking (software threads). Also can be used in conjunction with any third-party libraries for parallel computations (for the coordination and synchronization).

Version: 0.0.10

Initial release

Threading package is an implementation of the software threads.
Software threads executed in a single isolate and at the same time provides
behavior of the standard threads.
They can be called as a software emulation because they does not executed in
preemptive mode.
But on the other hand, they have only two limitations:

  • Executed in a single isolate
  • Does not switches the context by the hardware interrupt

In all other cases they are works like the normal threads executed on an
uniprocessor system in cooperative mode.

Features

  • Sleep, join and interrupt threads
  • Acquire, release locks
  • Wait, signal and broadcast by condition variables

Examples:

example/example_interleaved_execution.dart

library threading.example.example_interleaved_execution;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  await runFutures();
  await runThreads();
}

Future runFutures() async {
  print("Futures (linear execution)");
  print("----------------");
  var futures = <Future>[];
  var numOfFutures = 3;
  var count = 3;
  for (var i = 0; i < numOfFutures; i++) {
    var name = new String.fromCharCode(65 + i);
    var thread = new Future(() async {
      for (var j = 0; j < count; j++) {
        await new Future.value();
        print("$name: $j");
      }
    });

    futures.add(thread);
  }

  await Future.wait(futures);
}

Future runThreads() async {
  print("Threads (interleaved execution)");
  print("----------------");
  var threads = <Thread>[];
  var numOfThreads = 3;
  var count = 3;
  for (var i = 0; i < numOfThreads; i++) {
    var name = new String.fromCharCode(65 + i);
    var thread = new Thread(() async {
      for (var j = 0; j < count; j++) {
        await new Future.value();
        print("$name: $j");
      }
    });

    threads.add(thread);
    await thread.start();
  }

  for (var i = 0; i < numOfThreads; i++) {
    await threads[i].join();
  }
}

Output:

Futures (linear execution)
----------------
A: 0
A: 1
A: 2
B: 0
B: 1
B: 2
C: 0
C: 1
C: 2
Threads (interleaved execution)
----------------
A: 0
A: 1
B: 0
A: 2
B: 1
C: 0
B: 2
C: 1
C: 2

example/example_producer_consumer_problem.dart

library threading.example.example_producer_consumer_problem;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  var length = 2;
  var buffer = new _BoundedBuffer(length);
  var total = length * 2;
  var consumed = 0;
  var produced = 0;
  var threads = <Thread>[];
  for (var i = 0; i < total; i++) {
    var thread = new Thread(() async {
      await buffer.put(i);
      print("${Thread.current.name}: => $i");
      produced++;
    });

    thread.name = "Producer $i";
    threads.add(thread);
    await thread.start();
  }

  for (var i = 0; i < total; i++) {
    var thread = new Thread(() async {
      var x = await buffer.take();
      print("${Thread.current.name}: <= $x");
      consumed++;
    });

    thread.name = "Consumer $i";
    threads.add(thread);
    await thread.start();
  }

  for (var thread in threads) {
    await thread.join();
  }

  print("Produced: $produced");
  print("Consumed: $consumed");
}

class _BoundedBuffer<T> {
  final int length;

  int _count = 0;

  List<T> _items;

  final Lock _lock = new Lock();

  ConditionVariable _notEmpty;

  ConditionVariable _notFull;

  int _putptr = 0;

  int _takeptr = 0;

  _BoundedBuffer(this.length) {
    _items = new List<T>(length);
    _notFull = new ConditionVariable(_lock);
    _notEmpty = new ConditionVariable(_lock);
  }

  Future put(T x) async {
    await _lock.acquire();
    try {
      while (_count == _items.length) {
        await _notFull.wait();
      }

      _items[_putptr] = x;
      if (++_putptr == _items.length) {
        _putptr = 0;
      }

      ++_count;
      await _notEmpty.signal();
    } finally {
      await _lock.release();
    }
  }

  Future<T> take() async {
    await _lock.acquire();
    try {
      while (_count == 0) {
        await _notEmpty.wait();
      }

      var x = _items[_takeptr];
      if (++_takeptr == _items.length) {
        _takeptr = 0;
      }

      --_count;
      await _notFull.signal();
      return x;
    } finally {
      await _lock.release();
    }
  }

  String toString() {
    return _items.sublist(0, _count).toString();
  }
}

Output:

Producer 0: => 0
Producer 1: => 1
Consumer 0: <= 0
Consumer 1: <= 1
Producer 2: => 2
Consumer 3: <= 2
Producer 3: => 3
Consumer 2: <= 3
Produced: 4
Consumed: 4

example/example_thread_join_1.dart

library threading.example.example_thread_join_1;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  var thread = new Thread(work);
  await thread.start();
  if (await thread.join(_waitTime * 2)) {
    print("New thread terminated.");
  } else {
    print("Join timed out.");
  }
}

final int _waitTime = 1000;

Future work() async {
  await Thread.sleep(_waitTime);
}

Output:

New thread terminated.

example/example_thread_timer_1.dart

library threading.example.example_thread_timer_1;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  var thread = new Thread(work);
  await thread.start();
  await thread.join();
  print("Thread terminated");
}

Future work() async {
  var sw = new Stopwatch();
  await sw.start();
  for (var i = 0; i < 2; i++) {
    new Timer(new Duration(milliseconds: 100), () {
      // This timer will sleep with thread
      print("Timer 100 ms, elapsed: ${sw.elapsedMilliseconds}");
    });

    new ThreadTimer(new Duration(milliseconds: 100), () {
      // This timer will be performed anyway
      print("ThreadTimer 100 ms, elapsed: ${sw.elapsedMilliseconds}");
    });
  }

  print("Thread sleep");
  await Thread.sleep(1000);
  print("Thread wake up after 1000 ms, elapsed: ${sw.elapsedMilliseconds}");
  sw.stop();
}

Output:

Thread sleep
ThreadTimer 100 ms, elapsed: 111
ThreadTimer 100 ms, elapsed: 114
Thread wake up after 1000 ms, elapsed: 1008
Timer 100 ms, elapsed: 1008
Timer 100 ms, elapsed: 1008
Thread terminated

example/example_thread_interrupt_2.dart

library threading.example.example_thread_interrupt_2;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  var t0 = new Thread(workAsync);
  //var t1 = new Thread(workSync);
  await t0.start();
  //await t1.start();
  await t0.join();
  //await t1.join();
  print("Done");
}

Future workAsync() async {
  new Future(() {
    print("Async: Future - should never be executed");
  });

  Timer.run(() {
    print("Async: Timer - should never be executed");
  });

  throw new ThreadInterruptException();
}

void workSync() {
  new Future(() {
    print("Sync: Future - should never be executed");
  });

  Timer.run(() {
    print("Sync: Timer - should never be executed");
  });

  throw new ThreadInterruptException();
}

Output:

Done

example/example_thread_interrupt_1.dart

library threading.example.example_thread_interrupt_1;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  var thread = new Thread(work);
  await thread.start();
  // The following line causes an exception to be thrown
  // in "work" if thread is currently blocked
  // or becomes blocked in the future.
  await thread.interrupt();
  print("Main thread calls interrupt on new thread.");
  // Tell newThread to go to sleep.
  _sleepSwitch = true;
  // Wait for new thread to end.
  await thread.join();
}

bool _sleepSwitch = false;

Future work() async {
  print("Thread is executing 'work'.");
  while (!_sleepSwitch) {
    print("work");
    await Thread.sleep(0);
  }

  try {
    print("Thread going to sleep.");
    // When thread goes to sleep, it is immediately
    // woken up by a ThreadInterruptException.
    await Thread.sleep(-1);
  } on ThreadInterruptException catch (e) {
    print("Thread cannot go to sleep - interrupted by main thread.");
  }
}

Output:

Thread is executing 'work'.
work
Main thread calls interrupt on new thread.

example/example_thread_join_2.dart

library threading.example.example_thread_join_2;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  var t1 = new Thread(() async {
    await Thread.sleep(2000);
    print("t1 is ending.");
  });

  t1.start();
  var t2 = new Thread(() async {
    await Thread.sleep(1000);
    print("t2 is ending.");
  });

  t2.start();
  await t1.join();
  print("t1.Join() returned.");
  await t2.join();
  print("t2.Join() returned.");
}

Output:

t2 is ending.
t1 is ending.
t1.Join() returned.
t2.Join() returned.

example/example_thread_interrupt_3.dart

library threading.example.example_thread_interrupt_3;

import "dart:async";

import "package:threading/threading.dart";

Future main() async {
  print("Main thread starting");
  var secondThread = new Thread(threadJob);
  await secondThread.start();
  print("Main thread sleeping");
  await Thread.sleep(500);
  await _lock.acquire();
  try {
    print("Main thread acquired lock - signaling monitor");
    await _lock.signal();
    print("Monitor signaled; interrupting second thread");
    await secondThread.interrupt();
    await Thread.sleep(1000);
    print("Main thread still owns lock...");
  } finally {
    await _lock.release();
  }
}

Lock _lock = new Lock();

Future threadJob() async {
  print("Second thread starting");
  await _lock.acquire();
  try {
    print("Second thread acquired lock - about to wait");
    try {
      await _lock.wait();
    } catch (e) {
      print("Second thread caught an exception: $e");
    }
  } finally {
    await _lock.release();
  }
}

Output:

Main thread starting
Main thread sleeping
Second thread starting
Second thread acquired lock - about to wait
Main thread acquired lock - signaling monitor
Monitor signaled; interrupting second thread
Main thread still owns lock...
Second thread caught an exception: ThreadInterruptException

0.0.9

  • Adaptation to Dart 2.0

0.0.8

  • Minor bug fixes

0.0.7

  • Minor bug fixes
  • Minor improvements in the scheduling and interleaving of the threads

0.0.6

  • Bug fixes

0.0.5

  • Bug fixes
  • Solved the problem with sleeping microtasks

0.0.4

  • Fixed bug with exception injection. Has the effect on interruption of the passive threads

0.0.3

  • Added public getter Thread.state

0.0.2

  • Added an example example_producer_consumer_problem.dart. Also known as the bounded-buffer problem

0.0.1

  • Initial release

example/example.dart

library threading.example.example;

import "dart:async";

import "example_interleaved_execution.dart" as example_interleaved_execution;
import "example_producer_consumer_problem.dart"
    as example_producer_consumer_problem;
import "example_thread_interrupt_1.dart" as example_thread_interrupt_1;
import "example_thread_interrupt_2.dart" as example_thread_interrupt_2;
import "example_thread_interrupt_3.dart" as example_thread_interrupt_3;
import "example_thread_join_1.dart" as example_thread_join_1;
import "example_thread_join_2.dart" as example_thread_join_2;
import "example_thread_timer_1.dart" as example_thread_timer_1;

Future main() async {
  await runExample(
      "Example: Interleaved Execution", example_interleaved_execution.main);
  await runExample("Example: Producer-consumer problem",
      example_producer_consumer_problem.main);
  await runExample(
      "Example: Thread Interrupt 1", example_thread_interrupt_1.main);
  await runExample(
      "Example: Thread Interrupt 2", example_thread_interrupt_2.main);
  await runExample(
      "Example: Thread Interrupt 3", example_thread_interrupt_3.main);
  await runExample("Example: Thread Join 1", example_thread_join_1.main);
  await runExample("Example: Thread Join 2", example_thread_join_2.main);
  await runExample("Example: Thread Timer 1", example_thread_timer_1.main);
}

Future runExample(String name, Future example()) async {
  print("================");
  print(name);
  print("----------------");
  await example();
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  threading: ^0.0.10

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:threading/threading.dart';
  
Version Uploaded Documentation Archive
0.0.10 Jul 27, 2018 Go to the documentation of threading 0.0.10 Download threading 0.0.10 archive
0.0.9 Jul 25, 2018 Go to the documentation of threading 0.0.9 Download threading 0.0.9 archive
0.0.8 Jun 9, 2015 Go to the documentation of threading 0.0.8 Download threading 0.0.8 archive
0.0.7 Jun 3, 2015 Go to the documentation of threading 0.0.7 Download threading 0.0.7 archive
0.0.6 May 31, 2015 Go to the documentation of threading 0.0.6 Download threading 0.0.6 archive
0.0.5 May 31, 2015 Go to the documentation of threading 0.0.5 Download threading 0.0.5 archive
0.0.4 May 30, 2015 Go to the documentation of threading 0.0.4 Download threading 0.0.4 archive
0.0.3 May 30, 2015 Go to the documentation of threading 0.0.3 Download threading 0.0.3 archive
0.0.2 May 29, 2015 Go to the documentation of threading 0.0.2 Download threading 0.0.2 archive
0.0.1 May 29, 2015 Go to the documentation of threading 0.0.1 Download threading 0.0.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
65
Health:
Code health derived from static analysis. [more]
99
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
82
Learn more about scoring.

We analyzed this package on Aug 10, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.11.8

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:threading/threading.dart.

Suggestions

Package is pre-v1 release.

While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction of the API.

The description is too long.

Search engines will display only the first part of the description. Try to keep it under 180 characters.

Fix lib/src/threading/thread.dart.

Analysis of lib/src/threading/thread.dart reported 2 hints:

line 55 col 8: The value of the field '_timedOut' isn't used.

line 59 col 12: The value of the field '_wakeupTime' isn't used.

Format lib/src/threading/event_loop.dart.

Run dartfmt to format lib/src/threading/event_loop.dart.

Format lib/src/threading/thread_state.dart.

Run dartfmt to format lib/src/threading/thread_state.dart.

Format lib/src/threading/zone_handle.dart.

Run dartfmt to format lib/src/threading/zone_handle.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.60.0 <3.0.0
Dev dependencies
build_tools any
file_utils any
path any
test any