admin管理员组文章数量:1599527
上一篇介绍了Mutex 的作用和实现,在多线程中,使用mutex 可以实现对全局变量的加锁保护,也就是在访问(读写)这个变量之前先要获取对应的锁,然后才能访问。在多线中还有这样的场景,某个线程需要等另外一个线程完成了某些操作,然后再“通知”这个线程往下执行,这就需要使用到condition,下面给出具体的实例。
frameworks/av/include/media/stagefright/foundation/ALooper.h
72 Mutex mLock;
73 Condition mQueueChangedCondition;
首先定义了mLock 和 mQueueChangedCondition 这两个成员变量。
frameworks/av/media/libstagefright/foundation/ALooper.cpp
194 bool ALooper::loop() {
195 Event event;
196
197 {
198 Mutex::Autolock autoLock(mLock); //在调用wait()或者waitRelative()必须先获取锁
199 if (mThread == NULL && !mRunningLocally) {
200 return false;
201 }
202 if (mEventQueue.empty()) { //如果队列为空,则一直等待signal()
203 mQueueChangedCondition.wait(mLock);
204 return true;
205 }
206 int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
207 int64_t nowUs = GetNowUs();
208
209 if (whenUs > nowUs) {
210 int64_t delayUs = whenUs - nowUs;
211 mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); //等待signal(),如果超时也会返回
212
213 return true;
214 }
215
216 event = *mEventQueue.begin();
217 mEventQueue.erase(mEventQueue.begin());
218 }
...
227 return true;
228 }
上面这个是ALooper 中实现loop()的关键代码,Mutex::Autolock autoLock(mLock); 是为了保护里面对一些变量的访问是互质的。如果mEventQueue 队列是空,跑到mQueueChangedCondition.wait(mLock); 就会一直在那里等待,等待其他线程往这个队列里面丢消息,然后通知它去处理。所以这个loop()里面的逻辑就是判断队列里面是否有消息要处理,如果没有就阻塞在那里等待,其实是会让出cpu,如果队列里面有消息,也会先判断是否需要马上处理,如果不需要马上处理,则等待需要delay 的时间后再处理,最后的消息处理逻辑也很简单,就是出队列中取出需要处理的消息,然后调用这个消息绑定的handler函数处理。
168 void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
169 Mutex::Autolock autoLock(mLock);
170
171 int64_t whenUs;
172 if (delayUs > 0) {
173 whenUs = GetNowUs() + delayUs;
174 } else {
175 whenUs = GetNowUs();
176 }
177
178 List<Event>::iterator it = mEventQueue.begin();
179 while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
180 ++it;
181 }
182
183 Event event;
184 event.mWhenUs = whenUs;
185 event.mMessage = msg;
186
187 if (it == mEventQueue.begin()) {
188 mQueueChangedCondition.signal();
189 }
190
191 mEventQueue.insert(it, event);
192 }
post()就是把消息丢到队列里面,然后通知looper 线程来处理,这里面的具体逻辑是如果插入的消息放在最前面,则通知looper 线程处理,否则只是插入到队列中的指定位置。上面的设计类似于一个 等待-通知 模型,而实现的关键就是利用了Condition 。
system/core/include/utils/Condition.h
44 class Condition {
...
56 Condition();
57 Condition(int type);
58 ~Condition();
59 // Wait on the condition variable. Lock the mutex before calling.
60 status_t wait(Mutex& mutex);
61 // same with relative timeout
62 status_t waitRelative(Mutex& mutex, nsecs_t reltime);
63 // Signal the condition variable, allowing exactly one thread to continue.
64 void signal();
65 // Signal the condition variable, allowing one or all threads to continue.
66 void signal(WakeUpType type) {
67 if (type == WAKE_UP_ONE) {
68 signal();
69 } else {
70 broadcast();
71 }
72 }
73 // Signal the condition variabl
版权声明:本文标题:android condition 详细介绍 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1728322384a1153992.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论