- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用大量socketio请求的应用程序,并且发出了批量请求。接收数据时,我必须遍历列表以添加和删除项:
List carlist;
void receiveData(Map data) {
// Need a lock here
for (var i = 0; i < carlist.lenght;) {
if (data[carlist[i]['name']]['color'] == carlist[i]['color']) {
carlist.removeAt(i);
onDeleteCar(data); // Update the UI.
}
}
// Need a release lock here
}
最佳答案
Dart没有并发线程,因此一个简单的 bool 变量可以用作互斥体。
如果您需要另一个异步执行来等待直到锁被释放然后继续,那么就不仅仅是返回,而是变得更加复杂了。
bool mutex = false;
void receiveData(Map data) {
// Need a lock here
if(mutex) {
return;
} else {
mutex = true;
}
for (var i = 0; i < carlist.lenght;) {
if (data[carlist[i]['name']]['color'] == carlist[i]['color']) {
carlist.removeAt(i);
onDeleteCar(data); // Update the UI.
}
}
// Need a release lock here
mutex = false;
}
import 'dart:async' as async;
import 'dart:collection' as coll;
import 'dart:math' as math;
void main() {
int j = 0;
int delay = 0;
for(int i = 0; i < 100; i++) {
new async.Future.delayed(
new Duration(milliseconds: delay += rnd.nextInt(150)),
() => receiveData({'${j++}': j}, j)
).catchError((e) => print('Error: $e'));
}
}
//List carlist = [];
WorkQueue workQueue = new WorkQueue(timeout: new Duration(milliseconds: 270));
math.Random rnd = new math.Random();
// had to made this async to make the timeout functionality work
// otherwise Dart would have evaluated the timeouts only after all other
// code has already been finished
async.Future receiveData(Map data, int id) {
// ensure that the code passed to add isn't entered by another async thread
// while it is already executed
// id is just for debugging purposes
return workQueue.add(id, () {
async.Completer completer = new async.Completer();
print('$id start');
// for (var i = 0; i < carlist.length;) {
// carlist.add(data);
// if (data[carlist[i]['name']]['color'] == carlist[i]['color']) {
// carlist.removeAt(i);
// onDeleteCar(data); // Update the UI.
// }
// }
// dummy task to burn time
new async.Future.delayed(new Duration(milliseconds: rnd.nextInt(100)), () {
var val = rnd.nextDouble();
// add some fun - check if code that throws is handled correctly
if(val > 0.9) {
completer.completeError('artifical error ${id}');
print('$id end with error');
} else {
completer.complete();
print('$id end');
}
});
return completer.future;
});
// Need a release lock here
}
// just holds a completer and a closure
class Task {
// complete after f was executed
async.Completer completer = new async.Completer();
// this code should only be entered by one thread at a time
Function f;
// only for debugging purposes
int id;
// ignore timeout if f has already been invoked
bool isInvoked = false;
Task(this.id, this.f, Duration timeout){
if(timeout != null) {
completer.future.timeout(timeout, onTimeout: () {
if(!completer.isCompleted && !isInvoked) {
completer.completeError('${id} timed out');
}
})
// future.timeout creates a new Future which also throws when
// the completer is completed with completeError
// not handling this error ends the app with unhandled exception
.catchError((_) {});
}
}
}
class WorkQueue {
// enque all calls
coll.Queue q = new coll.Queue();
// currently executing?
bool isExecuting = false;
// throw when the execution is delayed longer than the provide timeout
Duration timeout;
WorkQueue({this.timeout});
// enqueue a new execution
async.Future add(int id, Function f) {
print('add $id - queue length: ${q.length}');
var t = new Task(id, f, timeout);
q.add(t);
// ensure that the queue is processed
new async.Future(release);
return t.completer.future;
}
// execute next waiting thread if any
void release() {
// do nothing if closure is currently being executed or queue is empty
if(!isExecuting && !q.isEmpty) {
isExecuting = true;
Task t = q.removeFirst();
// check if t hasn't alredy timed out
if(!t.completer.isCompleted) {
// ignore timeout because we are already being invoked
t.isInvoked = true;
// invoke the closure
new async.Future(t.f)
// handle errors in closure
.catchError((e) {
t.completer.completeError(e);
})
// process next Task in queue
.then((_) {
isExecuting = false;
new async.Future(release);
if(!t.completer.isCompleted) {
t.completer.complete();
}
});
}
}
}
}
add 1 - queue length: 0
1 start
1 end
add 2 - queue length: 0
2 start
add 3 - queue length: 0
2 end
3 start
3 end
add 4 - queue length: 0
4 start
4 end with error
Error: artifical error 4
add 5 - queue length: 0
5 start
5 end
add 6 - queue length: 0
6 start
add 7 - queue length: 0
6 end
7 start
7 end
add 8 - queue length: 0
8 start
add 9 - queue length: 0
add 10 - queue length: 1
8 end with error
Error: artifical error 8
9 start
9 end
10 start
add 11 - queue length: 0
10 end
11 start
add 12 - queue length: 0
add 13 - queue length: 1
11 end
12 start
12 end
13 start
13 end
add 14 - queue length: 0
14 start
14 end
add 15 - queue length: 0
15 start
add 16 - queue length: 0
15 end
16 start
16 end with error
Error: artifical error 16
add 17 - queue length: 0
17 start
17 end
add 18 - queue length: 0
18 start
18 end
add 19 - queue length: 0
19 start
add 20 - queue length: 0
19 end
20 start
add 21 - queue length: 0
20 end
21 start
add 22 - queue length: 0
21 end
22 start
22 end
add 23 - queue length: 0
23 start
23 end
add 24 - queue length: 0
24 start
add 25 - queue length: 0
add 26 - queue length: 1
add 27 - queue length: 2
24 end with error
Error: artifical error 24
25 start
add 28 - queue length: 2
add 29 - queue length: 3
25 end
26 start
add 30 - queue length: 3
26 end
27 start
27 end
28 start
add 31 - queue length: 2
28 end
29 start
29 end
30 start
30 end
31 start
add 32 - queue length: 0
31 end
32 start
32 end
add 33 - queue length: 0
33 start
33 end
add 34 - queue length: 0
34 start
34 end
add 35 - queue length: 0
35 start
35 end
add 36 - queue length: 0
36 start
add 37 - queue length: 0
36 end
37 start
add 38 - queue length: 0
37 end
38 start
add 39 - queue length: 0
38 end with error
Error: artifical error 38
39 start
39 end with error
Error: artifical error 39
add 40 - queue length: 0
40 start
add 41 - queue length: 0
40 end
41 start
41 end with error
Error: artifical error 41
add 42 - queue length: 0
42 start
add 43 - queue length: 0
add 44 - queue length: 1
add 45 - queue length: 2
42 end with error
Error: artifical error 42
43 start
add 46 - queue length: 2
43 end
44 start
add 47 - queue length: 2
add 48 - queue length: 3
add 49 - queue length: 4
44 end
45 start
add 50 - queue length: 4
45 end with error
Error: artifical error 45
46 start
46 end
47 start
add 51 - queue length: 3
47 end
48 start
Error: 49 timed out
48 end
add 52 - queue length: 2
Error: 50 timed out
add 53 - queue length: 3
add 54 - queue length: 4
add 55 - queue length: 5
Error: 51 timed out
add 56 - queue length: 6
Error: 52 timed out
add 57 - queue length: 7
Error: 53 timed out
Error: 54 timed out
add 58 - queue length: 8
Error: 55 timed out
add 59 - queue length: 9
Error: 56 timed out
Error: 57 timed out
add 60 - queue length: 10
Error: 58 timed out
add 61 - queue length: 11
Error: 59 timed out
add 62 - queue length: 12
add 63 - queue length: 13
Error: 60 timed out
add 64 - queue length: 14
Error: 61 timed out
Error: 62 timed out
add 65 - queue length: 15
Error: 63 timed out
add 66 - queue length: 16
Error: 64 timed out
add 67 - queue length: 17
Error: 65 timed out
add 68 - queue length: 18
Error: 66 timed out
add 69 - queue length: 19
add 70 - queue length: 20
add 71 - queue length: 21
Error: 67 timed out
add 72 - queue length: 22
Error: 68 timed out
add 73 - queue length: 23
Error: 69 timed out
Error: 70 timed out
Error: 71 timed out
add 74 - queue length: 24
Error: 72 timed out
Error: 73 timed out
add 75 - queue length: 25
add 76 - queue length: 26
Error: 74 timed out
add 77 - queue length: 27
add 78 - queue length: 28
Error: 75 timed out
Error: 76 timed out
add 79 - queue length: 29
add 80 - queue length: 30
Error: 77 timed out
Error: 78 timed out
add 81 - queue length: 31
add 82 - queue length: 32
add 83 - queue length: 33
Error: 79 timed out
Error: 80 timed out
add 84 - queue length: 34
Error: 81 timed out
add 85 - queue length: 35
Error: 82 timed out
Error: 83 timed out
add 86 - queue length: 36
Error: 84 timed out
add 87 - queue length: 37
Error: 85 timed out
add 88 - queue length: 38
add 89 - queue length: 39
add 90 - queue length: 40
add 91 - queue length: 41
Error: 86 timed out
add 92 - queue length: 42
Error: 87 timed out
Error: 88 timed out
add 93 - queue length: 43
Error: 89 timed out
Error: 90 timed out
Error: 91 timed out
Error: 92 timed out
add 94 - queue length: 44
add 95 - queue length: 45
add 96 - queue length: 46
add 97 - queue length: 47
Error: 93 timed out
add 98 - queue length: 48
Error: 94 timed out
Error: 95 timed out
Error: 96 timed out
add 99 - queue length: 49
Error: 97 timed out
add 100 - queue length: 50
Error: 98 timed out
Error: 99 timed out
Error: 100 timed out
关于locking - 我需要Dart中的Mutex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25067164/
我需要在一个函数内锁定一个 std::map 和两个 boost::multimaps 的操作,因为我们有线程试图访问该函数(以及映射)。 我计划使用“std::mutex mutex_var”来保护
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭11 年前。 Improve th
或不同的标题: 为什么处置获得的 Mutex 会破坏它? 我有以下代码,真正的代码在几个方法之间产生,并在这个方法休眠的地方做事: bool createdNew; u
如何测量互斥量、信号量或 futex 的延迟?我的意思是两个事件之间的延迟:解锁先前锁定的互斥体和锁定该互斥体。有两种情况:当所有线程/进程都在同一个 CPU 上时(重新调度线程需要多长时间)以及当第
我执行了以下程序,其中我创建了 100 个线程并发执行。请注意这是一个示例程序。我知道下面的程序不需要多线程,但我的目的是测试互斥量。 class ThreadPool{ public:
我有创建多个线程的代码,所有线程都尝试将信息记录在一个文件中我尝试使用互斥锁来登录文件,但是当我使用 Mutex() 和 Mutex(true or false, "name") 对象时,我得到了不同
我正在研究 Rust 示例。有这段代码: fn new(name: &str, left: usize, right: usize) -> Philosopher { Philosopher
我正在实现一个基于 std::queue 的 C++ 消息队列。 因为我需要 popers 在空队列上等待,所以我考虑使用 mutex 进行互斥,并使用 cond 在空队列上挂起线程,就像 glib
在golang中,sync.Mutex Lock和Unlock是usaul操作,但是Lock和defer Unlock的正确顺序是什么? mu.Lock() defer mu.Unlock() 或 d
在 Go 中,我们可以使用: type Data struct { lock *sync.Mutex } 或 type Data struct { lock sync.Mutex
我尝试摆脱代码中的一些 boost 依赖项,转而使用新的 C++11 功能 (Visual Studio 2013)。 在我的一个组件中,我使用了 boost::mutex与 boost::lock_
我正在使用 scoped_lock 和 mutex 来实现 BlockingQueue posted in a different SO question 的一个版本, 但在 boost 中有多个不同
我在互斥锁析构函数中遇到了上述错误。由于错误可能是由于互斥锁在销毁过程中处于锁定状态,所以我创建了一个新的互斥锁类,它继承自 boost:mutex。这是为了确保互斥锁在销毁期间解锁。但是,仍然会出现
今天写了一些代码来测试mutex的性能。 这是 boost(1.54) 版本,在 vs2010 上编译并进行了 O2 优化: boost::mutex m; auto start = boost::c
我不知道我没有做什么,但我根本无法让自己的调试器保存正在调试的应用程序的“Mutex Owned”或“Mutex Free”信息。 如果我按如下方式调用它,CDB 就可以正常工作: cdb -pn
还没有网上的例子来生动地演示这一点。在 http://en.cppreference.com/w/cpp/header/shared_mutex 看到了一个例子但目前还不清楚。有人可以帮忙吗? 最佳答
我有两个用例。 A.我想同步访问两个线程的队列。 B.我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。 对于用例 A,我看到了使用 std::lock_
我编写了一个小型 Go 库 ( go-patan ),用于收集某些变量的运行最小值/最大值/平均值/标准偏差。我将它与等效的 Java 实现 ( patan ) 进行了比较,令我惊讶的是 Java 实
我想知道这两者之间的区别是什么 boost::timed_mutex _mutex; if(_mutex.timed_lock(boost::get_system_time() + boost::po
我正在尝试将 dyn 特征存储在 Arc>>>> 中,但是由于某种原因它不起作用 use std::sync::{Arc, Mutex}; trait A{} struct B{} impl A fo
我是一名优秀的程序员,十分优秀!