Chromium 中chrome.cookies扩展接口c++实现分析

chrome.cookies

使用 chrome.cookies API 查询和修改 Cookie,并在 Cookie 发生更改时收到通知。

更多参考官网定义:chrome.cookies  |  API  |  Chrome for Developers (google.cn)

本文以加载一个清理cookies功能扩展为例 https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/api-samples/cookies/cookie-clearer

 摘自官网扩展例子:

manifest.json

{"name": "Cookie Clearer","manifest_version": 3,"version": "1.0","description": "Uses the chrome.cookies API by letting a user delete their cookies via a popup.","permissions": ["cookies"],"host_permissions": ["<all_urls>"],"action": {"default_popup": "popup.html"}
}

popup.js

const form = document.getElementById('control-row');
const input = document.getElementById('input');
const message = document.getElementById('message');// The async IIFE is necessary because Chrome <89 does not support top level await.
(async function initPopupWindow() {let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });if (tab?.url) {try {let url = new URL(tab.url);input.value = url.hostname;} catch {// ignore}}input.focus();
})();form.addEventListener('submit', handleFormSubmit);async function handleFormSubmit(event) {event.preventDefault();clearMessage();let url = stringToUrl(input.value);if (!url) {setMessage('Invalid URL');return;}let message = await deleteDomainCookies(url.hostname);setMessage(message);
}function stringToUrl(input) {// Start with treating the provided value as a URLtry {return new URL(input);} catch {// ignore}// If that fails, try assuming the provided input is an HTTP hosttry {return new URL('http://' + input);} catch {// ignore}// If that fails ¯\_(ツ)_/¯return null;
}async function deleteDomainCookies(domain) {let cookiesDeleted = 0;try {const cookies = await chrome.cookies.getAll({ domain });if (cookies.length === 0) {return 'No cookies found';}let pending = cookies.map(deleteCookie);await Promise.all(pending);cookiesDeleted = pending.length;} catch (error) {return `Unexpected error: ${error.message}`;}return `Deleted ${cookiesDeleted} cookie(s).`;
}function deleteCookie(cookie) {// Cookie deletion is largely modeled off of how deleting cookies works when using HTTP headers.// Specific flags on the cookie object like `secure` or `hostOnly` are not exposed for deletion// purposes. Instead, cookies are deleted by URL, name, and storeId. Unlike HTTP headers, though,// we don't have to delete cookies by setting Max-Age=0; we have a method for that ;)//// To remove cookies set with a Secure attribute, we must provide the correct protocol in the// details object's `url` property.// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Secureconst protocol = cookie.secure ? 'https:' : 'http:';// Note that the final URL may not be valid. The domain value for a standard cookie is prefixed// with a period (invalid) while cookies that are set to `cookie.hostOnly == true` do not have// this prefix (valid).// https://developer.chrome.com/docs/extensions/reference/cookies/#type-Cookieconst cookieUrl = `${protocol}//${cookie.domain}${cookie.path}`;return chrome.cookies.remove({url: cookieUrl,name: cookie.name,storeId: cookie.storeId});
}function setMessage(str) {message.textContent = str;message.hidden = false;
}function clearMessage() {message.hidden = true;message.textContent = '';
}

popup.html

<!doctype html>
<html><head><script src="popup.js" type="module"></script></head><body><form id="control-row"><label for="input">Domain:</label><input type="text" id="input" /><br /><button id="go">Clear Cookies</button></form><span id="message" hidden></span></body>
</html>

一、看下c++提供 的cookies接口定义  chrome\common\extensions\api\cookies.json

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.[{"namespace": "cookies","description": "Use the <code>chrome.cookies</code> API to query and modify cookies, and to be notified when they change.","types": [{"id": "SameSiteStatus","type": "string","enum": ["no_restriction", "lax", "strict", "unspecified"],"description": "A cookie's 'SameSite' state (https://tools.ietf.org/html/draft-west-first-party-cookies). 'no_restriction' corresponds to a cookie set with 'SameSite=None', 'lax' to 'SameSite=Lax', and 'strict' to 'SameSite=Strict'. 'unspecified' corresponds to a cookie set without the SameSite attribute."},{"id": "CookiePartitionKey","type": "object","description": "Represents a partitioned cookie's partition key.","properties": {"topLevelSite": {"type": "string", "optional": true, "description": "The top-level site the partitioned cookie is available in."}}},{"id": "Cookie","type": "object","description": "Represents information about an HTTP cookie.","properties": {"name": {"type": "string", "description": "The name of the cookie."},"value": {"type": "string", "description": "The value of the cookie."},"domain": {"type": "string", "description": "The domain of the cookie (e.g. \"www.google.com\", \"example.com\")."},"hostOnly": {"type": "boolean", "description": "True if the cookie is a host-only cookie (i.e. a request's host must exactly match the domain of the cookie)."},"path": {"type": "string", "description": "The path of the cookie."},"secure": {"type": "boolean", "description": "True if the cookie is marked as Secure (i.e. its scope is limited to secure channels, typically HTTPS)."},"httpOnly": {"type": "boolean", "description": "True if the cookie is marked as HttpOnly (i.e. the cookie is inaccessible to client-side scripts)."},"sameSite": {"$ref": "SameSiteStatus", "description": "The cookie's same-site status (i.e. whether the cookie is sent with cross-site requests)."},"session": {"type": "boolean", "description": "True if the cookie is a session cookie, as opposed to a persistent cookie with an expiration date."},"expirationDate": {"type": "number", "optional": true, "description": "The expiration date of the cookie as the number of seconds since the UNIX epoch. Not provided for session cookies."},"storeId": {"type": "string", "description": "The ID of the cookie store containing this cookie, as provided in getAllCookieStores()."},"partitionKey": {"$ref": "CookiePartitionKey", "optional": true, "description": "The partition key for reading or modifying cookies with the Partitioned attribute."}}},{"id": "CookieStore","type": "object","description": "Represents a cookie store in the browser. An incognito mode window, for instance, uses a separate cookie store from a non-incognito window.","properties": {"id": {"type": "string", "description": "The unique identifier for the cookie store."},"tabIds": {"type": "array", "items": {"type": "integer"}, "description": "Identifiers of all the browser tabs that share this cookie store."}}},{"id": "OnChangedCause","type": "string","enum": ["evicted", "expired", "explicit", "expired_overwrite", "overwrite"],"description": "The underlying reason behind the cookie's change. If a cookie was inserted, or removed via an explicit call to \"chrome.cookies.remove\", \"cause\" will be \"explicit\". If a cookie was automatically removed due to expiry, \"cause\" will be \"expired\". If a cookie was removed due to being overwritten with an already-expired expiration date, \"cause\" will be set to \"expired_overwrite\".  If a cookie was automatically removed due to garbage collection, \"cause\" will be \"evicted\".  If a cookie was automatically removed due to a \"set\" call that overwrote it, \"cause\" will be \"overwrite\". Plan your response accordingly."},{"id": "CookieDetails","type": "object","description": "Details to identify the cookie.","properties": {"url": {"type": "string", "description": "The URL with which the cookie to access is associated. This argument may be a full URL, in which case any data following the URL path (e.g. the query string) is simply ignored. If host permissions for this URL are not specified in the manifest file, the API call will fail."},"name": {"type": "string", "description": "The name of the cookie to access."},"storeId": {"type": "string", "optional": true, "description": "The ID of the cookie store in which to look for the cookie. By default, the current execution context's cookie store will be used."},"partitionKey": {"$ref": "CookiePartitionKey", "optional": true, "description": "The partition key for reading or modifying cookies with the Partitioned attribute."}}}],"functions": [{"name": "get","type": "function","description": "Retrieves information about a single cookie. If more than one cookie of the same name exists for the given URL, the one with the longest path will be returned. For cookies with the same path length, the cookie with the earliest creation time will be returned.","parameters": [{"name": "details","$ref": "CookieDetails"}],"returns_async": {"name": "callback","parameters": [{"name": "cookie", "$ref": "Cookie", "optional": true, "description": "Contains details about the cookie. This parameter is null if no such cookie was found."}]}},{"name": "getAll","type": "function","description": "Retrieves all cookies from a single cookie store that match the given information.  The cookies returned will be sorted, with those with the longest path first.  If multiple cookies have the same path length, those with the earliest creation time will be first. Only retrieves cookies for domains which the extension has host permissions to.","parameters": [{"type": "object","name": "details","description": "Information to filter the cookies being retrieved.","properties": {"url": {"type": "string", "optional": true, "description": "Restricts the retrieved cookies to those that would match the given URL."},"name": {"type": "string", "optional": true, "description": "Filters the cookies by name."},"domain": {"type": "string", "optional": true, "description": "Restricts the retrieved cookies to those whose domains match or are subdomains of this one."},"path": {"type": "string", "optional": true, "description": "Restricts the retrieved cookies to those whose path exactly matches this string."},"secure": {"type": "boolean", "optional": true, "description": "Filters the cookies by their Secure property."},"session": {"type": "boolean", "optional": true, "description": "Filters out session vs. persistent cookies."},"storeId": {"type": "string", "optional": true, "description": "The cookie store to retrieve cookies from. If omitted, the current execution context's cookie store will be used."},"partitionKey": {"$ref": "CookiePartitionKey", "optional": true, "description": "The partition key for reading or modifying cookies with the Partitioned attribute."}}}],"returns_async": {"name": "callback","parameters": [{"name": "cookies", "type": "array", "items": {"$ref": "Cookie"}, "description": "All the existing, unexpired cookies that match the given cookie info."}]}},{"name": "set","type": "function","description": "Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.","parameters": [{"type": "object","name": "details","description": "Details about the cookie being set.","properties": {"url": {"type": "string", "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain and path values of the created cookie. If host permissions for this URL are not specified in the manifest file, the API call will fail."},"name": {"type": "string", "optional": true, "description": "The name of the cookie. Empty by default if omitted."},"value": {"type": "string", "optional": true, "description": "The value of the cookie. Empty by default if omitted."},"domain": {"type": "string", "optional": true, "description": "The domain of the cookie. If omitted, the cookie becomes a host-only cookie."},"path": {"type": "string", "optional": true, "description": "The path of the cookie. Defaults to the path portion of the url parameter."},"secure": {"type": "boolean", "optional": true, "description": "Whether the cookie should be marked as Secure. Defaults to false."},"httpOnly": {"type": "boolean", "optional": true, "description": "Whether the cookie should be marked as HttpOnly. Defaults to false."},"sameSite": {"$ref": "SameSiteStatus", "optional": true, "description": "The cookie's same-site status. Defaults to \"unspecified\", i.e., if omitted, the cookie is set without specifying a SameSite attribute."},"expirationDate": {"type": "number", "optional": true, "description": "The expiration date of the cookie as the number of seconds since the UNIX epoch. If omitted, the cookie becomes a session cookie."},"storeId": {"type": "string", "optional": true, "description": "The ID of the cookie store in which to set the cookie. By default, the cookie is set in the current execution context's cookie store."},"partitionKey": {"$ref": "CookiePartitionKey", "optional": true, "description": "The partition key for reading or modifying cookies with the Partitioned attribute."}}}],"returns_async": {"name": "callback","optional": true,"min_version": "11.0.674.0","parameters": [{"name": "cookie", "$ref": "Cookie", "optional": true, "description": "Contains details about the cookie that's been set.  If setting failed for any reason, this will be \"null\", and $(ref:runtime.lastError) will be set."}]}},{"name": "remove","type": "function","description": "Deletes a cookie by name.","parameters": [{"name": "details","$ref": "CookieDetails"}],"returns_async": {"name": "callback","optional": true,"min_version": "11.0.674.0","parameters": [{"name": "details","type": "object","description": "Contains details about the cookie that's been removed.  If removal failed for any reason, this will be \"null\", and $(ref:runtime.lastError) will be set.","optional": true,"properties": {"url": {"type": "string", "description": "The URL associated with the cookie that's been removed."},"name": {"type": "string", "description": "The name of the cookie that's been removed."},"storeId": {"type": "string", "description": "The ID of the cookie store from which the cookie was removed."},"partitionKey": {"$ref": "CookiePartitionKey", "optional": true, "description": "The partition key for reading or modifying cookies with the Partitioned attribute."}}}]}},{"name": "getAllCookieStores","type": "function","description": "Lists all existing cookie stores.","parameters": [],"returns_async": {"name": "callback","parameters": [{"name": "cookieStores", "type": "array", "items": {"$ref": "CookieStore"}, "description": "All the existing cookie stores."}]}}],"events": [{"name": "onChanged","type": "function","description": "Fired when a cookie is set or removed. As a special case, note that updating a cookie's properties is implemented as a two step process: the cookie to be updated is first removed entirely, generating a notification with \"cause\" of \"overwrite\" .  Afterwards, a new cookie is written with the updated values, generating a second notification with \"cause\" \"explicit\".","parameters": [{"type": "object","name": "changeInfo","properties": {"removed": {"type": "boolean", "description": "True if a cookie was removed."},"cookie": {"$ref": "Cookie", "description": "Information about the cookie that was set or removed."},"cause": {"min_version": "12.0.707.0", "$ref": "OnChangedCause", "description": "The underlying reason behind the cookie's change."}}}]}]}
]

同时会生成

out\Debug\gen\chrome\common\extensions\api\cookies.h

out\Debug\gen\chrome\common\extensions\api\cookies.cc

此文件是cookies.json 定义的一个c++实现,自动生成请勿手动更改【tools\json_schema_compiler\compiler.py】。

二、cookies api接口定义:

       chrome\browser\extensions\api\cookies\cookies_api.h

       chrome\browser\extensions\api\cookies\cookies_api.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.// Defines the Chrome Extensions Cookies API functions for accessing internet
// cookies, as specified in the extension API JSON.#ifndef CHROME_BROWSER_EXTENSIONS_API_COOKIES_COOKIES_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_COOKIES_COOKIES_API_H_#include <memory>
#include <string>#include "base/memory/raw_ptr.h"
#include "base/values.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/common/extensions/api/cookies.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_function.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"class Profile;namespace extensions {// Observes CookieManager Mojo messages and routes them as events to the
// extension system.
class CookiesEventRouter : public BrowserListObserver {public:explicit CookiesEventRouter(content::BrowserContext* context);CookiesEventRouter(const CookiesEventRouter&) = delete;CookiesEventRouter& operator=(const CookiesEventRouter&) = delete;~CookiesEventRouter() override;// BrowserListObserver:void OnBrowserAdded(Browser* browser) override;private:// This helper class connects to the CookieMonster over Mojo, and relays Mojo// messages to the owning CookiesEventRouter. This rather clumsy arrangement// is necessary to differentiate which CookieMonster the Mojo message comes// from (that associated with the incognito profile vs the original profile),// since it's not possible to tell the source from inside OnCookieChange().class CookieChangeListener : public network::mojom::CookieChangeListener {public:CookieChangeListener(CookiesEventRouter* router, bool otr);CookieChangeListener(const CookieChangeListener&) = delete;CookieChangeListener& operator=(const CookieChangeListener&) = delete;~CookieChangeListener() override;// network::mojom::CookieChangeListener:void OnCookieChange(const net::CookieChangeInfo& change) override;private:raw_ptr<CookiesEventRouter> router_;bool otr_;};void MaybeStartListening();void BindToCookieManager(mojo::Receiver<network::mojom::CookieChangeListener>* receiver,Profile* profile);void OnConnectionError(mojo::Receiver<network::mojom::CookieChangeListener>* receiver);void OnCookieChange(bool otr, const net::CookieChangeInfo& change);// This method dispatches events to the extension message service.void DispatchEvent(content::BrowserContext* context,events::HistogramValue histogram_value,const std::string& event_name,base::Value::List event_args,const GURL& cookie_domain);raw_ptr<Profile> profile_;// To listen to cookie changes in both the original and the off the record// profiles, we need a pair of bindings, as well as a pair of// CookieChangeListener instances.CookieChangeListener listener_{this, false};mojo::Receiver<network::mojom::CookieChangeListener> receiver_{&listener_};CookieChangeListener otr_listener_{this, true};mojo::Receiver<network::mojom::CookieChangeListener> otr_receiver_{&otr_listener_};
};// Implements the cookies.get() extension function.
class CookiesGetFunction : public ExtensionFunction {public:DECLARE_EXTENSION_FUNCTION("cookies.get", COOKIES_GET)CookiesGetFunction();protected:~CookiesGetFunction() override;// ExtensionFunction:ResponseAction Run() override;private:void GetCookieListCallback(const net::CookieAccessResultList& cookie_list,const net::CookieAccessResultList& excluded_cookies);// Notify the extension telemetry service when API is called.void NotifyExtensionTelemetry();GURL url_;mojo::Remote<network::mojom::CookieManager> store_browser_cookie_manager_;absl::optional<api::cookies::Get::Params> parsed_args_;
};// Implements the cookies.getAll() extension function.
class CookiesGetAllFunction : public ExtensionFunction {public:DECLARE_EXTENSION_FUNCTION("cookies.getAll", COOKIES_GETALL)CookiesGetAllFunction();protected:~CookiesGetAllFunction() override;// ExtensionFunction:ResponseAction Run() override;private:// For the two different callback signatures for getting cookies for a URL vs// getting all cookies. They do the same thing.void GetAllCookiesCallback(const net::CookieList& cookie_list);void GetCookieListCallback(const net::CookieAccessResultList& cookie_list,const net::CookieAccessResultList& excluded_cookies);// Notify the extension telemetry service when API is called.void NotifyExtensionTelemetry();GURL url_;mojo::Remote<network::mojom::CookieManager> store_browser_cookie_manager_;absl::optional<api::cookies::GetAll::Params> parsed_args_;
};// Implements the cookies.set() extension function.
class CookiesSetFunction : public ExtensionFunction {public:DECLARE_EXTENSION_FUNCTION("cookies.set", COOKIES_SET)CookiesSetFunction();protected:~CookiesSetFunction() override;ResponseAction Run() override;private:void SetCanonicalCookieCallback(net::CookieAccessResult set_cookie_result);void GetCookieListCallback(const net::CookieAccessResultList& cookie_list,const net::CookieAccessResultList& excluded_cookies);enum { NO_RESPONSE, SET_COMPLETED, GET_COMPLETED } state_;GURL url_;bool success_;mojo::Remote<network::mojom::CookieManager> store_browser_cookie_manager_;absl::optional<api::cookies::Set::Params> parsed_args_;
};// Implements the cookies.remove() extension function.
class CookiesRemoveFunction : public ExtensionFunction {public:DECLARE_EXTENSION_FUNCTION("cookies.remove", COOKIES_REMOVE)CookiesRemoveFunction();protected:~CookiesRemoveFunction() override;// ExtensionFunction:ResponseAction Run() override;private:void RemoveCookieCallback(uint32_t /* num_deleted */);GURL url_;mojo::Remote<network::mojom::CookieManager> store_browser_cookie_manager_;absl::optional<api::cookies::Remove::Params> parsed_args_;
};// Implements the cookies.getAllCookieStores() extension function.
class CookiesGetAllCookieStoresFunction : public ExtensionFunction {public:DECLARE_EXTENSION_FUNCTION("cookies.getAllCookieStores",COOKIES_GETALLCOOKIESTORES)protected:~CookiesGetAllCookieStoresFunction() override {}// ExtensionFunction:ResponseAction Run() override;
};class CookiesAPI : public BrowserContextKeyedAPI, public EventRouter::Observer {public:explicit CookiesAPI(content::BrowserContext* context);CookiesAPI(const CookiesAPI&) = delete;CookiesAPI& operator=(const CookiesAPI&) = delete;~CookiesAPI() override;// KeyedService implementation.void Shutdown() override;// BrowserContextKeyedAPI implementation.static BrowserContextKeyedAPIFactory<CookiesAPI>* GetFactoryInstance();// EventRouter::Observer implementation.void OnListenerAdded(const EventListenerInfo& details) override;private:friend class BrowserContextKeyedAPIFactory<CookiesAPI>;raw_ptr<content::BrowserContext> browser_context_;// BrowserContextKeyedAPI implementation.static const char* service_name() {return "CookiesAPI";}static const bool kServiceIsNULLWhileTesting = true;// Created lazily upon OnListenerAdded.std::unique_ptr<CookiesEventRouter> cookies_event_router_;
};}  // namespace extensions#endif  // CHROME_BROWSER_EXTENSIONS_API_COOKIES_COOKIES_API_H_

三、开发者模式打开加载下扩展看下堆栈效果:

     

至此分析完毕,如果想拦截 chrome.cookies.getAll等方法在  chrome\browser\extensions\api\cookies\cookies_api.cc中更改即可。

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

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

相关文章

针对考研的C语言学习(循环队列-链表版本以及2019循环队列大题)

题目 【注】此版本严格按照数字版循环队列的写法&#xff0c;rear所代表的永远是空数据 图解 1.初始化部分和插入部分 2出队 3.分部代码解析 初始化 void init_cir_link_que(CirLinkQue& q) {q.rear q.front (LinkList)malloc(sizeof(LNode));q.front->next NULL…

Ansible 工具从入门到使用

1. Ansible概述 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主…

基于Zynq SDIO WiFi移植一(支持2.4/5G)

基于SDIO接口的WIFI&#xff0c;在应用上&#xff0c;功耗低于USB接口&#xff0c;且无须USB Device支持&#xff0c;满足某些应用场景 1 硬件连接 2 Vivado工程配置 3 驱动编译 3.1 KERNRL CONFIG (build ENV) 修改 export KERNELPATH<path of kernel header>export T…

一种压缩QRCode矩阵以用于存储的方法

通常QRCode由服务器生成&#xff0c;以图片格式发送到客户端&#xff0c;由客户端直接展示&#xff0c;也可以由客户端使用javascript或其他内置的SDK直接生成。 0、需求 QRCode生成过程中往往是先生成矩阵&#xff0c;然后使用矩阵生成图片&#xff0c;矩阵就是由01组成的一…

[单master节点k8s部署]35.ingress 反向代理(二)

成功部署ingress controller [rootmaster 35ingress]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-7dc5458bc6-fpv96 1/1 Running 10 (4d16h ago) 9d calico-…

自动化测试selenium篇(二)

1. 操作测试对象 1.1 普通操作 测试代码如下所示&#xff1a; private static void Test03() throws InterruptedException {//创建一个驱动WebDriver webDriver new ChromeDriver();//打开百度首页webDriver.get("https://www.baidu.com");//找到百度搜索输入框…

通过AI技术克服自动化测试难点(下)

前面的文章里我们对可以应用到测试中的AI技术做了整体介绍&#xff0c;详细介绍了OpenCV技术、OCR技术和神经网络&#xff0c;本文我们继续为大家介绍卷积神经网络、数据集以及AI技术在其他方面和测试相关的创新。 卷积神经网络整体上的原理是这样的&#xff0c;首先在底层特征…

【linux系统】进程

文章目录 进程和PCBlinux与进程的相关命令PS linux下的PCB进程标识符父子进程fork 进程状态磁盘睡眠 -- D暂停和跟踪暂停 -- T和t僵尸进程 -- Z孤儿进程 进程优先级 进程地址空间再谈fork进程地址空间分布虚拟地址和页表mm_struct 进程控制进程终止进程退出码信号 进程等待进程…

【翻译】在 Python 应用程序中使用Qt Designer的UI文件

原文地址&#xff1a;Using a Designer UI File in Your Qt for Python Application 直接上图&#xff0c;上代码 将UI文件转为Python 为了演示&#xff0c;我们使用 Qt Widgets 简单示例说明。 这个应用程序由一个源文件 easing.py、一个 UI 文件 form.UI、一个资源文件 ea…

考研笔记之操作系统(四) - 文件管理

文件管理 1. 简介1.1 前情回顾1.2 文件的属性1.3 文件内部数据的组织方式1.4 操作系统向上提供的文件功能1.5 文件应如何放在外存 2. 文件的逻辑结构2.1 无结构文件2.2 有结构文件2.2.1 顺序文件2.2.2 索引文件2.2.3 索引顺序文件2.2.4 多级索引顺序文件 3. 文件目录3.1 基本概…

1422. 分割字符串的最大得分【字符串】

文章目录 1422. 分割字符串的最大得分解题思路Go代码 1422. 分割字符串的最大得分 1422. 分割字符串的最大得分 给你一个由若干 0 和 1 组成的字符串 s &#xff0c;请你计算并返回将该字符串分割成两个 非空 子字符串&#xff08;即 左 子字符串和 右 子字符串&#xff09;所…

使用3080ti运行blip2的

使用3080ti运行blip2的案例 注意&#xff01;blip2很吃显存&#xff0c;需要大于80GB显存的卡。我最后安装的所有包的版本信息&#xff08;python 3.9 &#xff09;以供参考&#xff1a; 首先&#xff0c;我在运行blip2的demo的时候显存用了80G以上&#xff0c;所以大家卡的显存…

moectf-Web题解

1、弗拉格之地的入口 2、垫刀之路01: MoeCTF&#xff1f;启动&#xff01; 3、ez_http 4、ProveYourLove 5、弗拉格之地的挑战 6、ImageCloud前置 7、垫刀之路02: 普通的文件上传 8、垫刀之路03: 这是一个图床 9、垫刀之路05: 登陆网站 10、垫刀之路06: pop base mini …

Java值传递、序列化详解

Java 值传递详解 说到参数&#xff0c;我们先来搞懂一下这两个概念 形参&实参 值传递&引用传递 形参&实参 方法的定义可能会用到 参数&#xff08;有参的方法&#xff09;&#xff0c;参数在程序语言中分为&#xff1a; 实参&#xff08;实际参数&#xff0c;…

QT实现Opencv图像处理

案例 基于QT的人脸识别 pro文件需要加以下代码 INCLUDEPATH E:/opencv/opencv3.4-qt-intall/install/include INCLUDEPATH E:/opencv/opencv3.4-qt-intall/install/include/opencv INCLUDEPATH E:/opencv/opencv3.4-qt-intall/install/include/opencv2 LIBS E:/opencv/o…

D34【python 接口自动化学习】- python基础之输入输出与文件操作

day34 文件关闭 学习日期&#xff1a;20241011 学习目标&#xff1a;输入输出与文件操作&#xfe63;-46 常见常新&#xff1a;文件的关闭 学习笔记&#xff1a; 文件关闭的内部工作过程 close&#xff08;&#xff09;函数 with语句 常用的打开关闭文件 # 文件关闭 # 方式…

值类型和引用类型的使用

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp1 {class Program{static void Main(string[] args){/****值类型****/bool test;//必须赋值,否则报错test true;Console.WriteLin…

微服务_3.微服务保护

文章目录 一、微服务雪崩及解决方法1.1、超时处理1.2、仓壁模式1.3、断路器1.4、限流 二、Sentinel2.1、流量控制2.1.1、普通限流2.1.2、热点参数限流 2.2、线程隔离2.3、熔断降级2.3.1、断路器状态机2.3.2、断路器熔断策略2.3.2.1、慢调用2.3.2.2、异常比例&#xff0c;异常数…

Observability:使用 OpenTelemetry 自动检测 Go 应用程序

作者&#xff1a;来自 Elastic Damien Mathieu 使用 OpenTelemetry 检测 Go 应用程序可以深入了解应用程序的性能、依赖项和错误。我们将向你展示如何使用 Docker 自动检测 Go 应用程序&#xff0c;而无需更改应用程序代码。 在快节奏的软件开发领域&#xff0c;尤其是在云原生…

【每日刷题】Day137

【每日刷题】Day137 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; 2. 495. 提莫攻击 - 力扣&#xf…