IPC

来源:互联网 发布:淘宝旺旺名是什么意思 编辑:程序博客网 时间:2024/06/05 06:01

创建

子进程的主线程创建的时候会创建一个通信管道,用于和主进程进行通信。

void ChildThreadImpl::Init(const Options& options) {    ......  channel_ =      IPC::SyncChannel::Create(this, ChildProcess::current()->io_task_runner(),                               ChildProcess::current()->GetShutDownEvent());    ......

这里创建的是一个SyncChannel的支持同步的channel。传递的是this,为当前线程指针,
然后又传递了IO线程的任务运行runner,最后传递的时候关闭事件的通知。

// staticscoped_ptr<SyncChannel> SyncChannel::Create(    Listener* listener,    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,    WaitableEvent* shutdown_event) {  return make_scoped_ptr(      new SyncChannel(listener, ipc_task_runner, shutdown_event));}SyncChannel::SyncChannel(    Listener* listener,    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,    WaitableEvent* shutdown_event)    : ChannelProxy(new SyncContext(listener, ipc_task_runner, shutdown_event)) {  // The current (listener) thread must be distinct from the IPC thread, or else  // sending synchronous messages will deadlock.  DCHECK_NE(ipc_task_runner.get(), base::ThreadTaskRunnerHandle::Get().get());  StartWatching();}

SyncChannel实现的是同步机制,而内部继承自ChannelProxy,后者实现后台线程机制,也就是说将listenner线程即主线程,ipc_task_runner线程即IO线程分开。
换句话说,SyncChannel负责进行同步异步的发送消息,如果是同步发送,那么在发送之后堵塞当前线程等待结果,如果是异步发送,那么使用ChannelProxy来发送消息后立即返回。

发送

如下是一个发送与接收的过程,这是一个GPU进程从IO线程上接收到GpuMsg_Initialize_Meta,经过处理,然后发送给IO线程的流程栈

3:030> kL # Child-SP          RetAddr           Call Site00 00000000`001fcfa8 000007fe`e69cde7e chrome_child!IPC::ChannelProxy::Context::Send01 00000000`001fcfb0 000007fe`e69cab28 chrome_child!IPC::ChannelProxy::Send+0x1202 00000000`001fcfe0 000007fe`e70397d0 chrome_child!IPC::SyncChannel::Send+0x13c03 00000000`001fd0e0 000007fe`e772a7c2 chrome_child!content::ChildThreadImpl::Send+0x3804 00000000`001fd110 000007fe`e772a27e chrome_child!content::GpuChildThread::OnInitialize+0xa205 (Inline Function) --------`-------- chrome_child!IPC::MessageT<GpuMsg_Initialize_Meta,std::tuple<>,void>::Dispatch+0x3a06 00000000`001fd290 000007fe`e703916d chrome_child!content::GpuChildThread::OnControlMessageReceived+0x42607 00000000`001fd430 000007fe`e772a9fe chrome_child!content::ChildThreadImpl::OnMessageReceived+0xd908 00000000`001fd590 000007fe`e69cda94 chrome_child!content::GpuChildThread::OnMessageReceived+0x2209 00000000`001fd6b0 000007fe`e55042a9 chrome_child!IPC::ChannelProxy::Context::OnDispatchMessage+0x1340a (Inline Function) --------`-------- chrome_child!base::Callback<void __cdecl(void)>::Run+0x80b 00000000`001fd7b0 000007fe`e54bfadc chrome_child!base::debug::TaskAnnotator::RunTask+0x1890c 00000000`001fd8a0 000007fe`e54c0624 chrome_child!base::MessageLoop::RunTask+0x3fc0d (Inline Function) --------`-------- chrome_child!base::MessageLoop::DeferOrRunPendingTask+0x1470e 00000000`001fe980 000007fe`e5502e48 chrome_child!base::MessageLoop::DoWork+0x4840f 00000000`001feb50 000007fe`e5502ad2 chrome_child!base::MessagePumpForUI::DoRunLoop+0x7810 00000000`001febc0 000007fe`e55029cf chrome_child!base::MessagePumpWin::Run+0x4211 (Inline Function) --------`-------- chrome_child!base::MessageLoop::RunHandler+0x1512 00000000`001fec00 000007fe`e54bee21 chrome_child!base::RunLoop::Run+0xdf13 00000000`001fec50 000007fe`e7728257 chrome_child!base::MessageLoop::Run+0x4114 00000000`001fecb0 000007fe`e68d0432 chrome_child!content::GpuMain+0x8bf15 00000000`001ff6c0 000007fe`e68d026f chrome_child!content::RunNamedProcessTypeMain+0x18e16 00000000`001ff830 000007fe`e68cd6c9 chrome_child!content::ContentMainRunnerImpl::Run+0x9317 00000000`001ff8c0 000007fe`e6842162 chrome_child!content::ContentMain+0x3518 00000000`001ff8f0 00000001`3f9e0f6f chrome_child!ChromeMain+0x8219 00000000`001ff980 00000001`3f9e01b0 chrome!MainDllLoader::Launch+0x3171a 00000000`001ffaa0 00000001`3fa1e018 chrome!wWinMain+0x2341b 00000000`001ffcc0 00000000`7778652d chrome!__tmainCRTStartup+0x1481c 00000000`001ffd00 00000000`779bc541 kernel32!BaseThreadInitThunk+0xd1d 00000000`001ffd30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

在最后,通过IO将消息发送出去

void ChannelProxy::Context::Send(Message* message) {  if (channel_send_thread_safe_) {    SendFromThisThread(message);    return;  }  ipc_task_runner()->PostTask(      FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this,                            base::Passed(scoped_ptr<Message>(message))));}

那么IO线程又是如何将消息发送的呢,也就是说当把消息派发给了IO线程后,IO线程又做了什么,我们在ChannelProxy::Context::OnSendMessage上下断,看看后续它怎么执行的。

3:036> kL # Child-SP          RetAddr           Call Site00 00000000`04e4e1d0 000007fe`e69d0ac5 kernel32!WriteFileImplementation+0x601 00000000`04e4e210 000007fe`e69d08b1 chrome_child!IPC::ChannelWin::ProcessOutgoingMessages+0x1bd02 00000000`04e4e360 000007fe`e69d0cfa chrome_child!IPC::ChannelWin::ProcessMessageForDelivery+0x27503 00000000`04e4e470 000007fe`e69cdd36 chrome_child!IPC::ChannelWin::Send+0x6204 00000000`04e4e4a0 000007fe`e710eef8 chrome_child!IPC::ChannelProxy::Context::OnSendMessage+0x7205 (Inline Function) --------`-------- chrome_child!base::internal::RunnableAdapter<void (__cdecl content::RTCPeerConnectionHandler::Observer::*)(scoped_ptr<content::RtcDataChannelHandler,std::default_delete<content::RtcDataChannelHandler> >)>::Run+0x2b06 (Inline Function) --------`-------- chrome_child!base::internal::InvokeHelper<0,void,base::internal::RunnableAdapter<void (__cdecl content::RTCPeerConnectionHandler::Observer::*)(scoped_ptr<content::RtcDataChannelHandler,std::default_delete<content::RtcDataChannelHandler> >)> >::MakeItSo+0x2b07 00000000`04e4e530 000007fe`e55042a9 chrome_child!base::internal::Invoker<base::IndexSequence<0,1>,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl content::RTCPeerConnectionHandler::Observer::*)(scoped_ptr<content::RtcDataChannelHandler,std::default_delete<content::RtcDataChannelHandler> >) __ptr64>,void __cdecl(content::RTCPeerConnectionHandler::Observer * __ptr64,scoped_ptr<content::RtcDataChannelHandler,std::default_delete<content::RtcDataChannelHandler> >),content::RTCPeerConnectionHandler::Observer * __ptr64 const,base::internal::PassedWrapper<scoped_ptr<content::RtcDataChannelHandler,std::default_delete<content::RtcDataChannelHandler> > > >,base::internal::InvokeHelper<0,void,base::internal::RunnableAdapter<void (__cdecl content::RTCPeerConnectionHandler::Observer::*)(scoped_ptr<content::RtcDataChannelHandler,std::default_delete<content::RtcDataChannelHandler> >) __ptr64> >,void __cdecl(void)>::Run+0x4c08 (Inline Function) --------`-------- chrome_child!base::Callback<void __cdecl(void)>::Run+0x809 00000000`04e4e570 000007fe`e54bfadc chrome_child!base::debug::TaskAnnotator::RunTask+0x1890a 00000000`04e4e660 000007fe`e54c0624 chrome_child!base::MessageLoop::RunTask+0x3fc0b (Inline Function) --------`-------- chrome_child!base::MessageLoop::DeferOrRunPendingTask+0x1470c 00000000`04e4f740 000007fe`e550360a chrome_child!base::MessageLoop::DoWork+0x4840d 00000000`04e4f910 000007fe`e5502ad2 chrome_child!base::MessagePumpForIO::DoRunLoop+0xaa0e 00000000`04e4f940 000007fe`e55029cf chrome_child!base::MessagePumpWin::Run+0x420f (Inline Function) --------`-------- chrome_child!base::MessageLoop::RunHandler+0x1510 00000000`04e4f980 000007fe`e54e1ad1 chrome_child!base::RunLoop::Run+0xdf11 (Inline Function) --------`-------- chrome_child!base::MessageLoop::Run+0x3512 00000000`04e4f9d0 000007fe`e54e1e28 chrome_child!base::Thread::Run+0x4113 00000000`04e4fa30 000007fe`e54eb6ed chrome_child!base::Thread::ThreadMain+0x33814 00000000`04e4faa0 00000000`7778652d chrome_child!base::`anonymous namespace'::ThreadFunc+0x15d15 00000000`04e4fb10 00000000`779bc541 kernel32!BaseThreadInitThunk+0xd16 00000000`04e4fb40 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

windows 上通过写文件将数据传递到命名管道上。

接收

我们在发送的时候,就已经看到部分接收的堆栈了。当IPC线程接收到消息的时候。堆栈如下

3:040> kL # Child-SP          RetAddr           Call Site00 00000000`04f1f8c8 000007fe`e3bba3f5 chrome_child!IPC::ChannelProxy::Context::OnMessageReceivedNoFilter01 00000000`04f1f8d0 000007fe`e3bc1eed chrome_child!IPC::SyncChannel::SyncContext::OnMessageReceived+0x7102 00000000`04f1f900 000007fe`e3bc2406 chrome_child!IPC::internal::ChannelReader::DispatchMessageW+0x2103 00000000`04f1f930 000007fe`e3bc255d chrome_child!IPC::internal::ChannelReader::HandleExternalMessage+0x9a04 00000000`04f1f980 000007fe`e3bc2818 chrome_child!IPC::internal::ChannelReader::HandleTranslatedMessage+0x9905 00000000`04f1f9b0 000007fe`e3bc1d8d chrome_child!IPC::internal::ChannelReader::TranslateInputData+0xc406 00000000`04f1fa80 000007fe`e3bc035c chrome_child!IPC::internal::ChannelReader::AsyncReadComplete+0x1507 00000000`04f1fab0 000007fe`e26f37b6 chrome_child!IPC::ChannelWin::OnIOCompleted+0xac08 00000000`04f1fae0 000007fe`e26f35a0 chrome_child!base::MessagePumpForIO::WaitForIOCompletion+0x18609 00000000`04f1fb50 000007fe`e26f2ad2 chrome_child!base::MessagePumpForIO::DoRunLoop+0x400a 00000000`04f1fb80 000007fe`e26f29cf chrome_child!base::MessagePumpWin::Run+0x420b (Inline Function) --------`-------- chrome_child!base::MessageLoop::RunHandler+0x150c 00000000`04f1fbc0 000007fe`e26d1ad1 chrome_child!base::RunLoop::Run+0xdf0d (Inline Function) --------`-------- chrome_child!base::MessageLoop::Run+0x350e 00000000`04f1fc10 000007fe`e26d1e28 chrome_child!base::Thread::Run+0x410f 00000000`04f1fc70 000007fe`e26db6ed chrome_child!base::Thread::ThreadMain+0x33810 00000000`04f1fce0 00000000`7740652d chrome_child!base::`anonymous namespace'::ThreadFunc+0x15d11 00000000`04f1fd50 00000000`7763c541 kernel32!BaseThreadInitThunk+0xd12 00000000`04f1fd80 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

IO 线程中收到一个IO完成的通知,然后派发和处理这个消息,接着如下这样,将消息派发到Listener线程即主线程中。

// Called on the IPC::Channel threadbool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {  listener_task_runner_->PostTask(      FROM_HERE, base::Bind(&Context::OnDispatchMessage, this, message));  return true;}

之后的堆栈就如上面的发送中的堆栈所示,收到了一个GpuMsg_Initialize_Meta消息,将这个消息进行处理之后在发送给IO线程。

0 0