在chromium中如何创建线程
base::Thread thread("test");
thread.Start();
//thread.StartWithOptions(base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
创建线程对象后,可以调用Start,或者StartWithOptions指定创建线程的一些选项。
Thread::Thread(const std::string& name)
: id_event_(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED),
name_(name),
start_event_(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED) {
}
Thread的构造函数里创建了一个id_event,和start_event的WaitableEvent对象,同时把name赋值给name_变量。
bool Thread::Start() {
DCHECK(owning_sequence_checker_.CalledOnValidSequence());
Options options;
#if defined(OS_WIN)
if (com_status_ == STA)
options.message_loop_type = MessageLoop::TYPE_UI;
#endif
return StartWithOptions(options);
}
调用Start会创建一个默认Option,调用StartWithOptions.
bool Thread::StartWithOptions(const Options& options) {
// Reset |id_| here to support restarting the thread.
id_event_.Reset();
id_ = kInvalidThreadId;
SetThreadWasQuitProperly(false);
MessageLoop::Type type = options.message_loop_type;
if (!options.message_pump_factory.is_null())
type = MessageLoop::TYPE_CUSTOM;
message_loop_timer_slack_ = options.timer_slack;
std::unique_ptr<MessageLoop> message_loop_owned =
MessageLoop::CreateUnbound(type, options.message_pump_factory);
message_loop_ = message_loop_owned.get();
start_event_.Reset();
// Hold |thread_lock_| while starting the new thread to synchronize with
// Stop() while it's not guaranteed to be sequenced (until crbug/629139 is
// fixed).
{
AutoLock lock(thread_lock_);
bool success =
options.joinable
? PlatformThread::CreateWithPriority(options.stack_size, this,
&thread_, options.priority)
: PlatformThread::CreateNonJoinableWithPriority(
options.stack_size, this, options.priority);
if (!success) {
DLOG(ERROR) << "failed to create thread";
message_loop_ = nullptr;
return false;
}
}
joinable_ = options.joinable;
// The ownership of |message_loop_| is managed by the newly created thread
// within the ThreadMain.
ignore_result(message_loop_owned.release());
DCHECK(message_loop_);
return true;
}
StartWithOptions中做了两件事,1.调用MessageLoop::CreateUnbound,2.调用PlatformThread::CreateWithPriority。
1.创建MessageLoop
std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound(
Type type,
MessagePumpFactoryCallback pump_factory) {
return WrapUnique(new MessageLoop(type, std::move(pump_factory)));
}
MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory)
: MessageLoopCurrent(this),
type_(type),
pump_factory_(std::move(pump_factory)),
incoming_task_queue_(new internal::IncomingTaskQueue(this)),
unbound_task_runner_(
new internal::MessageLoopTaskRunner(incoming_task_queue_)),
task_runner_(unbound_task_runner_) {
}
MessageLoop::CreateUnbound静态函数,创建一个MessageLoop,MessageLoop中含有一个IncomingTaskQueue,MessageLoopTaskRunner。
2.调用PlatformThread::CreateWithPriority
这部分是由各个平台各自实现的, Posix平台的实现如下
// static
bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate,
PlatformThreadHandle* thread_handle,
ThreadPriority priority) {
return CreateThread(stack_size, true /* joinable thread */, delegate,
thread_handle, priority);
}
bool CreateThread(size_t stack_size,
bool joinable,
PlatformThread::Delegate* delegate,
PlatformThreadHandle* thread_handle,
ThreadPriority priority) {
base::InitThreading();
pthread_attr_t attributes;
pthread_attr_init(&attributes);
// Pthreads are joinable by default, so only specify the detached
// attribute if the thread should be non-joinable.
if (!joinable)
pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
// Get a better default if available.
if (stack_size == 0)
stack_size = base::GetDefaultThreadStackSize(attributes);
if (stack_size > 0)
pthread_attr_setstacksize(&attributes, stack_size);
std::unique_ptr<ThreadParams> params(new ThreadParams);
params->delegate = delegate;
params->joinable = joinable;
params->priority = priority;
pthread_t handle;
int err = pthread_create(&handle, &attributes, ThreadFunc, params.get());
bool success = !err;
if (success) {
// ThreadParams should be deleted on the created thread after used.
ignore_result(params.release());
} else {
// Value of |handle| is undefined if pthread_create fails.
handle = 0;
errno = err;
PLOG(ERROR) << "pthread_create";
}
*thread_handle = PlatformThreadHandle(handle);
pthread_attr_destroy(&attributes);
return success;
}
调用posix平台的pthread_create创建一个线程,然后调用ThreadFunc
void* ThreadFunc(void* params) {
PlatformThread::Delegate* delegate = nullptr;
{
std::unique_ptr<ThreadParams> thread_params(
static_cast<ThreadParams*>(params));
delegate = thread_params->delegate;
if (!thread_params->joinable)
base::ThreadRestrictions::SetSingletonAllowed(false);
#if !defined(OS_NACL)
// Threads on linux/android may inherit their priority from the thread
// where they were created. This explicitly sets the priority of all new
// threads.
PlatformThread::SetCurrentThreadPriority(thread_params->priority);
#endif
}
ThreadIdNameManager::GetInstance()->RegisterThread(
PlatformThread::CurrentHandle().platform_handle(),
PlatformThread::CurrentId());
delegate->ThreadMain();
ThreadIdNameManager::GetInstance()->RemoveName(
PlatformThread::CurrentHandle().platform_handle(),
PlatformThread::CurrentId());
base::TerminateOnThread();
return nullptr;
}
delegate为Thread, 会在线程中调用Thread::ThreadMain,退出这个方法后会调用base::TerminateOnThread()
void Thread::ThreadMain() {
id_event_.Signal();
// Complete the initialization of our Thread object.
PlatformThread::SetName(name_.c_str());
ANNOTATE_THREAD_NAME(name_.c_str()); // Tell the name to race detector.
// Lazily initialize the |message_loop| so that it can run on this thread.
DCHECK(message_loop_);
std::unique_ptr<MessageLoop> message_loop(message_loop_);
message_loop_->BindToCurrentThread();
message_loop_->SetTimerSlack(message_loop_timer_slack_);
#if defined(OS_POSIX) && !defined(OS_NACL)
// Allow threads running a MessageLoopForIO to use FileDescriptorWatcher API.
std::unique_ptr<FileDescriptorWatcher> file_descriptor_watcher;
if (MessageLoopForIO::IsCurrent()) {
file_descriptor_watcher.reset(new FileDescriptorWatcher(
static_cast<MessageLoopForIO*>(message_loop_)));
}
#endif
// Let the thread do extra initialization.
Init();
{
AutoLock lock(running_lock_);
running_ = true;
}
start_event_.Signal();
RunLoop run_loop;
run_loop_ = &run_loop;
Run(run_loop_);
{
AutoLock lock(running_lock_);
running_ = false;
}
// Let the thread do extra cleanup.
CleanUp();
// We can't receive messages anymore.
// (The message loop is destructed at the end of this block)
message_loop_ = nullptr;
run_loop_ = nullptr;
}
ThreadMain中会调用MessageLoop的bindToCurrentThread
void MessageLoop::BindToCurrentThread() {
DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
DCHECK(!pump_);
if (!pump_factory_.is_null())
pump_ = std::move(pump_factory_).Run();
else
pump_ = CreateMessagePumpForType(type_);
DCHECK(!MessageLoopCurrent::IsSet())
<< "should only have one message loop per thread";
MessageLoopCurrent::BindToCurrentThreadInternal(this);
incoming_task_queue_->StartScheduling();
unbound_task_runner_->BindToCurrentThread();
unbound_task_runner_ = nullptr;
SetThreadTaskRunnerHandle();
thread_id_ = PlatformThread::CurrentId();
scoped_set_sequence_local_storage_map_for_current_thread_ = std::make_unique<
internal::ScopedSetSequenceLocalStorageMapForCurrentThread>(
&sequence_local_storage_map_);
RunLoop::RegisterDelegateForCurrentThread(this);
}
其中会创建MessageLoopPump,IncomingTaskQueue::StartScheduing, TaskRunner::BindToCurrentThread。
ThreadMain中还会调用Run(RunLoop* run_loop)
void Thread::Run(RunLoop* run_loop) {
// Overridable protected method to be called from our |thread_| only.
DCHECK(id_event_.IsSignaled());
DCHECK_EQ(id_, PlatformThread::CurrentId());
run_loop->Run();
}
void RunLoop::Run() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!BeforeRun())
return;
const bool application_tasks_allowed =
delegate_->active_run_loops_.size() == 1U ||
type_ == Type::kNestableTasksAllowed;
delegate_->Run(application_tasks_allowed);
// Rebind this RunLoop to the current thread after Run().
DETACH_FROM_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
AfterRun();
}
delegate为MessageLoop,RunLoop::Run调用MessageLoop::Run
void MessageLoop::Run(bool application_tasks_allowed) {
DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
if (application_tasks_allowed && !task_execution_allowed_) {
// Allow nested task execution as explicitly requested.
DCHECK(RunLoop::IsNestedOnCurrentThread());
task_execution_allowed_ = true;
pump_->Run(this);
task_execution_allowed_ = false;
} else {
pump_->Run(this);
}
}
最后会调用MessageLoopPump的Run方法, MessageLoopPump根据MessageLoop的不同type会创建不同的子类,默认是MessagePumpDefault。
void MessagePumpDefault::Run(Delegate* delegate) {
AutoReset<bool> auto_reset_keep_running(&keep_running_, true);
for (;;) {
bool did_work = delegate->DoWork();
if (!keep_running_)
break;
did_work |= delegate->DoDelayedWork(&delayed_work_time_);
if (!keep_running_)
break;
if (did_work)
continue;
did_work = delegate->DoIdleWork();
if (!keep_running_)
break;
if (did_work)
continue;
ThreadRestrictions::ScopedAllowWait allow_wait;
if (delayed_work_time_.is_null()) {
event_.Wait();
} else {
// No need to handle already expired |delayed_work_time_| in any special
// way. When |delayed_work_time_| is in the past TimeWaitUntil returns
// promptly and |delayed_work_time_| will re-initialized on a next
// DoDelayedWork call which has to be called in order to get here again.
event_.TimedWaitUntil(delayed_work_time_);
}
// Since event_ is auto-reset, we don't need to do anything special here
// other than service each delegate method.
}
}
MessageLoopPump的作用就是启动一个消息循环,然后去schedule delegate去做一些work。delegate是MessageLoop
网友评论