Chromium Mojo(IPC)进程通信演示 c++(2)

122版本自带的mojom通信例子associated-interface 仅供学习参考:

codelabs\mojo_examples\02-associated-interface-freezing

一、目录结构如图:

二、interface.mojom接口

1、codelabs\mojo_examples\mojom\interface.mojom

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.module codelabs.mojom;// Bound in the renderer process; only used in
// `02-associated-interface-freezing` and
// `03-channel-associated-interface-freezing`.
interface ObjectA {// A sample IPC send to the toy "renderer".DoA();
};// Bound in the renderer process.
interface ObjectB {// A sample IPC send to the toy "renderer".DoB();
};// This is a simple generic interface that serves no purpose but to transport a
// message handle from the browser to the renderer. It's just a handle, so it
// requires more type information to actually bind the handle properly on the
// other end (see `Process.GetAssociatedInterface()`).
interface GenericInterface {};// A process-wide interface that the renderer uses to broker new connections to
// other associated interfaces (see `ObjectA` and `ObjectB` above). This is a
// toy version of `blink.mojom.AssociatedInterfaceProvider`, the mechanism by
// which we bind associated interfaces that span the real browser <=> renderer
// processes in Chromium.
interface Process {// A sample IPC send to the toy "renderer"; used by the `01-multi-process`// example.SayHello();// Because we're transporting a generic handle, we need more information to// bind it properly in the toy "renderer" process, which is what the "name"// argument provides.GetAssociatedInterface(string name, pending_associated_receiver<GenericInterface> receiver);
};

自动生成 

out\Debug\gen\codelabs\mojo_examples\mojom\interface.mojom.h

out\Debug\gen\codelabs\mojo_examples\mojom\interface.mojom.cc等文件。 

2、BUILD.gn

codelabs\mojo_examples\mojom\BUILD.gn

import("//mojo/public/tools/bindings/mojom.gni")mojom("mojom") {sources = [ "interface.mojom" ]public_deps = ["//ipc:mojom","//ipc:mojom_constants",]deps = ["//ipc:mojom","//ipc:mojom_constants",]# Don't generate a variant sources since we depend on generated internal# bindings types and we don't generate or build variants of those.disable_variants = true
}

3、ObjectA和ObjectB接口实现:

codelabs\mojo_examples\mojo_impls.h

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.#ifndef CODELABS_MOJO_EXAMPLES_MOJO_IMPLS_H_
#define CODELABS_MOJO_EXAMPLES_MOJO_IMPLS_H_#include "base/task/single_thread_task_runner.h"
#include "codelabs/mojo_examples/mojom/interface.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"// The classes here are implementations of the mojo interfaces in this
// directory that some of the examples use. They are global instances whose
// receivers get bound to task runners associated with different task queues.
// `ObjectAImpl` is bound to a task queue that is initially frozen, and
// `ObjectBImpl` is bound to the current thread's default task runner,
// associated with an unfrozen task queue.
class ObjectAImpl : public codelabs::mojom::ObjectA {public:ObjectAImpl();~ObjectAImpl() override;void BindToFrozenTaskRunner(mojo::PendingAssociatedReceiver<codelabs::mojom::ObjectA>pending_receiver,scoped_refptr<base::SingleThreadTaskRunner> freezable_tq_runner);private:// codelabs::mojom::ObjectAvoid DoA() override;mojo::AssociatedReceiver<codelabs::mojom::ObjectA> receiver_{this};
};// The global instance of this class is bound to an unfrozen task queue, but
// doesn't receive any messages until the frozen task queue that manages
// `ObjectAImpl`'s is finally unfroze, after a delay.
class ObjectBImpl : public codelabs::mojom::ObjectB {public:ObjectBImpl();~ObjectBImpl() override;void Bind(mojo::PendingAssociatedReceiver<codelabs::mojom::ObjectB>pending_receiver);private:// codelabs::mojom::ObjectBvoid DoB() override;mojo::AssociatedReceiver<codelabs::mojom::ObjectB> receiver_{this};
};#endif  // CODELABS_MOJO_EXAMPLES_MOJO_IMPLS_H_

codelabs\mojo_examples\mojo_impls.cc 

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.#include "codelabs/mojo_examples/mojo_impls.h"#include "base/logging.h"ObjectAImpl::ObjectAImpl() = default;
ObjectAImpl::~ObjectAImpl() = default;void ObjectAImpl::BindToFrozenTaskRunner(mojo::PendingAssociatedReceiver<codelabs::mojom::ObjectA> pending_receiver,scoped_refptr<base::SingleThreadTaskRunner> freezable_tq_runner) {receiver_.Bind(std::move(pending_receiver), std::move(freezable_tq_runner));
}void ObjectAImpl::DoA() {LOG(INFO) << "DoA IPC is being processed!";
}ObjectBImpl::ObjectBImpl() = default;
ObjectBImpl::~ObjectBImpl() = default;void ObjectBImpl::Bind(mojo::PendingAssociatedReceiver<codelabs::mojom::ObjectB>pending_receiver) {receiver_.Bind(std::move(pending_receiver));
}void ObjectBImpl::DoB() {LOG(INFO) << "DoB IPC is being processed!";
}

三、02-mojo-browser.exe

codelabs\mojo_examples\02-associated-interface-freezing\browser.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.#include "base/command_line.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/run_loop.h"
#include "codelabs/mojo_examples/mojom/interface.mojom.h"
#include "codelabs/mojo_examples/process_bootstrapper.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"mojo::ScopedMessagePipeHandle LaunchAndConnect() {// Under the hood, this is essentially always an OS pipe (domain socket pair,// Windows named pipe, mach port, Fuchsia channel, etc).mojo::PlatformChannel channel;mojo::OutgoingInvitation invitation;// Attach a message pipe to be extracted by the receiver. The other end of the// pipe is returned for us to use locally.mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe("pipe");base::LaunchOptions options;// This is the relative path to the mock "renderer process" binary. We pass it// into `base::LaunchProcess` to run the binary in a new process.static const base::CommandLine::CharType* argv[] = {FILE_PATH_LITERAL("./02-mojo-renderer")};base::CommandLine command_line(1, argv);channel.PrepareToPassRemoteEndpoint(&options, &command_line);LOG(INFO) << "Browser: " << command_line.GetCommandLineString();base::Process child_process = base::LaunchProcess(command_line, options);channel.RemoteProcessLaunchAttempted();mojo::OutgoingInvitation::Send(std::move(invitation), child_process.Handle(),channel.TakeLocalEndpoint());return pipe;
}void CreateProcessRemote(mojo::ScopedMessagePipeHandle pipe) {// An unassociated remote to the toy "renderer" process. We us this to bind// two associated interface requests.mojo::PendingRemote<codelabs::mojom::Process> pending_remote(std::move(pipe),/*version=*/0u);mojo::Remote<codelabs::mojom::Process> remote(std::move(pending_remote));remote->SayHello();// Make an associated interface request for ObjectA and send an IPC.mojo::PendingAssociatedRemote<codelabs::mojom::GenericInterface>pending_generic;remote->GetAssociatedInterface("ObjectA", pending_generic.InitWithNewEndpointAndPassReceiver());mojo::PendingAssociatedRemote<codelabs::mojom::ObjectA> pending_a(pending_generic.PassHandle(), /*version=*/0u);mojo::AssociatedRemote<codelabs::mojom::ObjectA> remote_a(std::move(pending_a));LOG(INFO) << "Calling ObjectA::DoA() from the browser";remote_a->DoA();// Do the same for ObjectB.mojo::PendingAssociatedRemote<codelabs::mojom::GenericInterface>pending_generic_2;remote->GetAssociatedInterface("ObjectB", pending_generic_2.InitWithNewEndpointAndPassReceiver());mojo::PendingAssociatedRemote<codelabs::mojom::ObjectB> pending_b(pending_generic_2.PassHandle(), /*version=*/0u);mojo::AssociatedRemote<codelabs::mojom::ObjectB> remote_b(std::move(pending_b));LOG(INFO) << "Calling ObjectB::DoB() from the browser";remote_b->DoB();
}int main(int argc, char** argv) {LOG(INFO) << "Browser process starting up";base::CommandLine::Init(argc, argv);ProcessBootstrapper bootstrapper;bootstrapper.InitMainThread(base::MessagePumpType::IO);bootstrapper.InitMojo(/*as_browser_process=*/true);mojo::ScopedMessagePipeHandle pipe = LaunchAndConnect();base::SequencedTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE, base::BindOnce(&CreateProcessRemote, std::move(pipe)));base::RunLoop run_loop;// Delay shutdown of the browser process for visual effects, as well as to// ensure the browser process doesn't die while the IPC message is still being// sent to the target process asynchronously, which would prevent its// delivery. This delay is an arbitrary 5 seconds, which just needs to be// longer than the renderer's 3 seconds, which is used to show visually via// logging, how the ordering of IPCs can be effected by a frozen task queue// that gets unfrozen 3 seconds later.base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(FROM_HERE,base::BindOnce([](base::OnceClosure quit_closure) {LOG(INFO) << "'Browser process' shutting down";std::move(quit_closure).Run();},run_loop.QuitClosure()),base::Seconds(5));run_loop.Run();return 0;
}

四、02-mojo-renderer.exe

codelabs\mojo_examples\02-associated-interface-freezing\renderer.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.#include <memory>#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/task/sequence_manager/task_queue.h"
#include "codelabs/mojo_examples/mojo_impls.h"
#include "codelabs/mojo_examples/mojom/interface.mojom.h"
#include "codelabs/mojo_examples/process_bootstrapper.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"static ObjectAImpl g_object_a;
static ObjectBImpl g_object_b;class ProcessImpl : public codelabs::mojom::Process {public:ProcessImpl(mojo::PendingReceiver<codelabs::mojom::Process> pending_receiver,scoped_refptr<base::SingleThreadTaskRunner> freezable_tq_runner) {receiver_.Bind(std::move(pending_receiver));freezable_tq_runner_ = std::move(freezable_tq_runner);}private:// codelabs::mojo::Processvoid SayHello() override {LOG(INFO) << "Hello! (invoked in the renderer, from the browser)";}void GetAssociatedInterface(const std::string& name,mojo::PendingAssociatedReceiver<codelabs::mojom::GenericInterface>receiver) override {LOG(INFO) << "Renderer: GetAssociatedInterface() for " << name;if (name == "ObjectA") {mojo::PendingAssociatedReceiver<codelabs::mojom::ObjectA> pending_a(receiver.PassHandle());g_object_a.BindToFrozenTaskRunner(std::move(pending_a),std::move(freezable_tq_runner_));} else if (name == "ObjectB") {mojo::PendingAssociatedReceiver<codelabs::mojom::ObjectB> pending_b(receiver.PassHandle());g_object_b.Bind(std::move(pending_b));}}mojo::Receiver<codelabs::mojom::Process> receiver_{this};// This is a freezable task runner that only `g_object_a` gets bound to.scoped_refptr<base::SingleThreadTaskRunner> freezable_tq_runner_;
};static std::unique_ptr<ProcessImpl> g_process_impl;class CustomTaskQueue : public base::RefCounted<CustomTaskQueue> {public:CustomTaskQueue(base::sequence_manager::SequenceManager& sequence_manager,const base::sequence_manager::TaskQueue::Spec& spec): task_queue_(sequence_manager.CreateTaskQueue(spec)),voter_(task_queue_->CreateQueueEnabledVoter()) {}void FreezeTaskQueue() { voter_->SetVoteToEnable(false); }void UnfreezeTaskQueue() {LOG(INFO) << "Unfreezing the task queue that `ObjectAImpl` is bound to.";voter_->SetVoteToEnable(true);}const scoped_refptr<base::SingleThreadTaskRunner>& task_runner() const {return task_queue_->task_runner();}private:~CustomTaskQueue() = default;friend class base::RefCounted<CustomTaskQueue>;base::sequence_manager::TaskQueue::Handle task_queue_;// Used to enable/disable the underlying `TaskQueueImpl`.std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> voter_;
};int main(int argc, char** argv) {base::CommandLine::Init(argc, argv);LOG(INFO) << "Renderer: "<< base::CommandLine::ForCurrentProcess()->GetCommandLineString();// Set up the scheduling infrastructure for this process. It consists of://   1.) A SequenceManager that is bound to the current thread (main thread)//   2.) A default task queue//   3.) A `CustomTaskQueue` that is easily freezable and unfreezable. This//   part is specific to this example.ProcessBootstrapper bootstrapper;bootstrapper.InitMainThread(base::MessagePumpType::IO);bootstrapper.InitMojo(/*as_browser_process=*/false);scoped_refptr<CustomTaskQueue> freezable_tq =base::MakeRefCounted<CustomTaskQueue>(*bootstrapper.sequence_manager.get(),base::sequence_manager::TaskQueue::Spec(base::sequence_manager::QueueName::TEST_TQ));freezable_tq->FreezeTaskQueue();// Accept an invitation.mojo::IncomingInvitation invitation = mojo::IncomingInvitation::Accept(mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(*base::CommandLine::ForCurrentProcess()));mojo::ScopedMessagePipeHandle pipe = invitation.ExtractMessagePipe("pipe");base::RunLoop run_loop;// Post a task that will run in 3 seconds, that will unfreeze the custom task// queue to which the `codelabs::mojom::ObjectA` object is bound to.base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(FROM_HERE,base::BindOnce([](scoped_refptr<CustomTaskQueue> freezable_tq) {freezable_tq->UnfreezeTaskQueue();},freezable_tq),base::Seconds(3));// Create a process-wide receiver that will broker connects to the backing// `codelabs::mojom::ObjectA` and `codelabs::mojom::ObjectB` implementations.mojo::PendingReceiver<codelabs::mojom::Process> pending_receiver(std::move(pipe));g_process_impl = std::make_unique<ProcessImpl>(std::move(pending_receiver),freezable_tq->task_runner());run_loop.Run();return 0;
}

五、ProcessBootstrapper辅助类

codelabs\mojo_examples\process_bootstrapper.h

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.#ifndef CODELABS_MOJO_EXAMPLES_PROCESS_BOOTSTRAPPER_H_
#define CODELABS_MOJO_EXAMPLES_PROCESS_BOOTSTRAPPER_H_#include "base/message_loop/message_pump.h"
#include "base/run_loop.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/threading/thread.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/embedder/scoped_ipc_support.h"class ProcessBootstrapper {public:ProcessBootstrapper();~ProcessBootstrapper();// This sets up the main thread with a message pump of `type`, and optionally// a dedicated IO thread if `type` is *not* `base::MessagePumpType::IO`.void InitMainThread(base::MessagePumpType type) {// Creates a sequence manager bound to the main thread with a message pump// of some specified type. The message pump determines exactly what the// event loop on its thread is capable of (i.e., what *kind* of messages it// can "pump"). For example, a `DEFAULT` message pump is capable of// processing simple events, like async timers and posted tasks. The `IO`// message pump type — which is used in every example in this codelab — is// capable of asynchronously processing IO over IPC primitives like file// descriptors, used by Mojo. A thread with *that* kind of message pump is// required for any process using Mojo for IPC.std::unique_ptr<base::MessagePump> pump = base::MessagePump::Create(type);sequence_manager =base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(std::move(pump),base::sequence_manager::SequenceManager::Settings::Builder().SetMessagePumpType(type).Build());default_tq = std::make_unique<base::sequence_manager::TaskQueue::Handle>(sequence_manager->CreateTaskQueue(base::sequence_manager::TaskQueue::Spec(base::sequence_manager::QueueName::DEFAULT_TQ)));sequence_manager->SetDefaultTaskRunner((*default_tq)->task_runner());if (type == base::MessagePumpType::DEFAULT) {InitDedicatedIOThread();}}// Must be called after `InitMainThread()`.void InitMojo(bool as_browser_process) {CHECK(default_tq) << "Must call `InitMainThread()` before `InitMojo()`";// Basic Mojo initialization for a new process.mojo::core::Configuration config;// For mojo, one process must be the broker process which is responsible for// trusted cross-process introductions etc. Traditionally this is the// "browser" process.config.is_broker_process = as_browser_process;mojo::core::Init(config);// The effects of `ScopedIPCSupport` are mostly irrelevant for our simple// examples, but this class is used to determine how the IPC system shuts// down. The two shutdown options are "CLEAN" and "FAST", and each of these// may determine how other processes behave if *this* process has a message// pipe that is in the middle of proxying messages to another process where// the other end of the message pipe lives.//// In real Chrome, both the browser and renderer processes can safely use// `FAST` mode, because the side effects of quickly terminating the IPC// system in the middle of cross-process IPC message proxying is not// important. See this class's documentation for more information on// shutdown.//// We initialize `ipc_support` with a task runner for whatever thread should// be the IO thread. This means preferring `io_task_runner` when it is// non-null, and the default task runner otherwise.mojo::core::ScopedIPCSupport ipc_support(io_task_runner ? io_task_runner : (*default_tq)->task_runner(),mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);}std::unique_ptr<base::sequence_manager::TaskQueue::Handle> default_tq;std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager;scoped_refptr<base::SingleThreadTaskRunner> io_task_runner;private:// Note that you cannot call this if you've ever called// `InitMainThread(base::MessagePumpType::IO)` since that means the main// thread *itself* the IO thread.void InitDedicatedIOThread() {io_thread_ = std::make_unique<base::Thread>("ipc!");io_thread_->StartWithOptions(base::Thread::Options(base::MessagePumpType::IO, 0));io_task_runner = io_thread_->task_runner();}std::unique_ptr<base::Thread> io_thread_;
};ProcessBootstrapper::ProcessBootstrapper() = default;
ProcessBootstrapper::~ProcessBootstrapper() = default;#endif  // CODELABS_MOJO_EXAMPLES_PROCESS_BOOTSTRAPPER_H_

六、codelabs\mojo_examples\BUILD.gn

# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.group("codelab_mojo_examples") {testonly = true# These examples rely on base::LaunchOptions which do not exist in the iOS# simulator.if (!is_ios) {deps = [":01-mojo-browser",":01-mojo-renderer",":02-mojo-browser",":02-mojo-renderer",":03-mojo-browser",":03-mojo-renderer",]}
}if (!is_ios) {executable("01-mojo-browser") {deps = ["//base","//codelabs/mojo_examples/mojom","//ipc","//mojo/core/embedder","//mojo/public/cpp/platform","//mojo/public/mojom/base",]sources = ["01-multi-process/browser.cc","process_bootstrapper.h",]}executable("01-mojo-renderer") {deps = ["//base","//codelabs/mojo_examples/mojom","//ipc","//mojo/core/embedder","//mojo/public/cpp/platform","//mojo/public/mojom/base",]sources = ["01-multi-process/renderer.cc","process_bootstrapper.h",]}executable("02-mojo-browser") {deps = ["//base","//codelabs/mojo_examples/mojom","//ipc","//mojo/core/embedder","//mojo/public/cpp/platform","//mojo/public/mojom/base",]sources = ["02-associated-interface-freezing/browser.cc","process_bootstrapper.h",]}executable("02-mojo-renderer") {deps = ["//base","//codelabs/mojo_examples/mojom","//ipc","//mojo/core/embedder","//mojo/public/cpp/platform","//mojo/public/mojom/base",]sources = ["02-associated-interface-freezing/renderer.cc","mojo_impls.cc","mojo_impls.h","process_bootstrapper.h",]}executable("03-mojo-browser") {deps = ["//base","//codelabs/mojo_examples/mojom","//ipc","//mojo/core/embedder","//mojo/public/cpp/platform","//mojo/public/mojom/base",]sources = ["03-channel-associated-interface-freezing/browser.cc","process_bootstrapper.h",]}executable("03-mojo-renderer") {deps = ["//base","//codelabs/mojo_examples/mojom","//ipc","//mojo/core/embedder","//mojo/public/cpp/platform","//mojo/public/mojom/base",]sources = ["03-channel-associated-interface-freezing/renderer.cc","mojo_impls.cc","mojo_impls.h","process_bootstrapper.h",]}
}

七、编译和调试:

  1、gn gen out/debug

自动生成如下文件:  

2、 ninja -C out/debug 02-mojo-browser

生成02-mojo-browser.exe

3、ninja -C out/debug 02-mojo-renderer

生成02-mojo-renderer.exe

4、最终生成文件:

八、总结:

1、02-mojo-browser.exe 与02-mojo-renderer.exe通过mojo::OutgoingInvitation模式建立链接。

2、02-mojo-browser.exe通过GetAssociatedInterface接口获取02-mojo-renderer.exe进程对应的

ObjectA和ObjectB接口,并且调用其方法DoA(),DoB()。

更多细节读者自行参考源码。

Chromium Mojo(IPC)进程通信演示 c++(3)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/885589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用

本篇将带你实现一个番茄钟倒计时应用&#xff0c;用户可以设置专注时间和休息时间的时长&#xff0c;点击“开始专注”或“开始休息”按钮启动计时&#xff0c;应用会在倒计时结束时进行提醒。番茄钟应用对于管理时间、提升工作效率非常有帮助&#xff0c;并且还会加入猫咪图片…

u盘怎么重装电脑系统_u盘重装电脑系统步骤和详细教程【新手宝典】

u盘怎么重装电脑系统&#xff1f;一个u盘怎么重装电脑系统呢&#xff0c;需要将u盘制作成u盘启动盘pe&#xff0c;然后通过U盘启动盘进入pe进行安装系统&#xff0c;下面小编就教大家u盘重装电脑系统步骤和详细教程。 u盘启动是什么意思&#xff1f; U盘启动盘是一种具有特殊功…

Typora导出pdf手动分页和设置字体样式

手动分页 <div style"page-break-after: always;"></div>鼠标点击代码才会显示&#xff0c;不点击会隐藏。导出pdf时&#xff0c;该位置会分页 设置字体大小、加粗、居中、空格 <p style"font-size:30px; font-weight: bold; text-align: cen…

简简单单的UDP

前言 上一篇了解了TCP的三次握手过程&#xff0c;目的、以及如何保证可靠性、序列号与ACK的作用&#xff0c;最后离开的时候四次挥手的内容&#xff0c;这还只是TCP内容中的冰山一角&#xff0c;是不是觉得TCP这个协议非常复杂&#xff0c;这一篇我们来了解下传输层另外一个协…

淘宝/天猫按图搜索商品:taobao.item_search_img API的奇幻之旅

在这个看脸的时代&#xff0c;我们不仅对人要看颜值&#xff0c;连买东西都要“看脸”了。没错&#xff0c;我说的就是淘宝/天猫的按图搜索商品功能——taobao.item_search_img API。这个功能就像是电商平台的“人脸识别”&#xff0c;只不过它认的是商品的颜值。下面&#xff…

软件工程 软考

开发大型软件系统适用螺旋模型或者RUP模型 螺旋模型强调了风险分析&#xff0c;特别适用于庞大而复杂的、高风险的管理信息系统的开发。喷泉模型是一种以用户需求为动力&#xff0c;以对象为为驱动的模型&#xff0c;主要用于描述面向对象的软件开发过程。该模型的各个阶段没有…

STM32F405RGT6单片机原理图、PCB免费分享

大学时机创比赛时画的板子&#xff0c;比到一半因为疫情回家&#xff0c;无后续&#xff0c;&#xff0c;&#xff0c;已打板验证过&#xff0c;使用stm32f405rgt6做主控 下载文件资源如下 原理图文件 pcb文件 外壳模型文件 stm32f405例程 功能 以下功能全部验证通过 4路…

写一个记录函数执行时间的装饰器

装饰器&#xff0c;这可是Python开发中绕不开的经典话题&#xff0c;不论你是写代码的老手&#xff0c;还是刚入行的萌新&#xff0c;都得和它打上几轮交道。而记录函数执行时间这个功能&#xff0c;更是装饰器中的“常客”。 今天我就带大家来全面解锁一下这块儿的知识&#…

Python 桌面应用开发:使用 Tkinter 创建 GUI 应用程序

Python 桌面应用开发&#xff1a;使用 Tkinter 创建 GUI 应用程序 引言 随着计算机技术的飞速发展&#xff0c;桌面应用程序依然在许多领域中发挥着重要作用。Python 作为一种强大的编程语言&#xff0c;提供了多种工具和库来创建桌面应用程序。其中&#xff0c;Tkinter 是 P…

vue3入门知识(一)

vue3简介 性能的提升 打包大小减少41%初次渲染快55%&#xff0c;更新渲染快133%内存减少54% 源码的升级 使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和Tree-Shaking 新的特性 1. Composition API&#xff08;组合API&#xff09; setupref与reactivecomput…

AI与就业:技术革命下的职业转型与挑战

内容概要 在当今时代&#xff0c;人工智能的迅猛发展正在深刻影响着我们的就业市场。这一技术革命不仅让我们看到了未来的职业转型&#xff0c;还引发了对于新兴技能需求的深思。随着AI技术的普及&#xff0c;许多传统行业面临着巨大的变革压力&#xff0c;同时也为新兴领域创…

小白初入Android_studio所遇到的坑以及怎么解决

1. 安装Android_studio 参考&#xff1a;Android Studio 安装配置教程 - Windows(详细版)-CSDN博客 Android Studio超级详细讲解下载、安装配置教程&#xff08;建议收藏&#xff09;_androidstudio-CSDN博客 想下旧版本的android_studio的地址&#xff08;仅供参考&#xf…

Uubntu下的Boost库安装及使用

一、Boost库介绍 Boost库是为C语言标准库提供扩展的一些C程序库的总称。 Boost库由Boost社区组织开发、维护。其目的是为C程序员提供免费、同行审查的、可移植的程序库。Boost库可以与C标准库共同工作&#xff0c;并且为其提供扩展功能。Boost库使用Boost License来授权使用&…

【王木头】最大似然估计、最大后验估计

目录 一、最大似然估计&#xff08;MLE&#xff09; 二、最大后验估计&#xff08;MAP&#xff09; 三、MLE 和 MAP 的本质区别 四、当先验是均匀分布时&#xff0c;MLE 和 MAP 等价 五、总结 本文理论参考王木头的视频&#xff1a; 贝叶斯解释“L1和L2正则化”&#xff…

「QT」几何数据类 之 QPointF 浮点型点类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…

数据结构与算法——Java实现 54.力扣1008题——前序遍历构造二叉搜索树

不要谩骂以前的自己 他当时一个人站在雾里也很迷茫 ​​​​​​​ ​​​​​​​ ​​​​​​​—— 24.11.6 1008. 前序遍历构造二叉搜索树 给定一个整数数组&#xff0c;它表示BST(即 二叉搜索树 )的 先序遍历 &#xff0c;构造树并返回其根。 保证 对于给定…

【Leecode】Leecode刷题之路第46天之全排列

题目出处 46-全排列-题目出处 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 46-全排列-官方解法 预备知识 回溯法&#xff1a;一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解…

势不可挡 创新引领 | 生信科技SOLIDWORKS 2025新品发布会·苏州站精彩回顾

2024年11月01日&#xff0c;由生信科技举办的SOLIDWORKS 2025新产品发布会在江苏苏州圆满落幕。现场邀请到制造业的专家学者们一同感受SOLIDWORKS 2025最新功能&#xff0c;探索制造业数字化转型之路。 在苏州站活动开场&#xff0c;达索系统专业客户事业部华东区渠道经理马腾飞…

CatLIP,加速2.7倍!采用分类损失的CLIP水准的预训练视觉编码器

CatLIP&#xff0c;加速2.7倍&#xff01;采用分类损失的CLIP水准的预训练视觉编码器 FesianXu 20241018 at Wechat Search Team 前言 传统的CLIP采用对比学习的方式进行预训练&#xff0c;通常需要汇聚多张节点的多张设备的特征向量以进行打分矩阵的计算&#xff0c;训练速度…

linux笔记(selinux)

一、概述 定义SELinux&#xff08;Security - Enhanced Linux&#xff09;是一种基于 Linux 内核的强制访问控制&#xff08;MAC&#xff09;安全机制。它为 Linux 系统提供了更细粒度的安全策略&#xff0c;增强了系统的安全性。目的主要目的是限制进程对系统资源&#xff08;…