当前位置: 首页 > news >正文

Linux:42线程控制lesson30

代码1:验证join可以去的线程执行完后的退出码/返回值

#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<string>
using namespace std;void* routine(void* arg){string name = static_cast<const char*>(arg);int cnt = 5;while(cnt--){cout<<"我是子线程,名字:"<<name<<endl;sleep(1);}return (void*)10;
}int main(){pthread_t tid;pthread_create(&tid,nullptr,routine,(void*)"thread-1");int cnt = 5;while(cnt--){cout<<"我是主线程"<<endl;sleep(1);}void* ret = nullptr;pthread_join(tid,&ret);cout<<"子进程退出,退出码为:"<<(long long)ret<<endl;
}

 

1.main函数结束,代表主线程结束,也代表进程结束
2.新线程对应的入口函数,运行结束,代表当前线程运行结束
3.问题:给线程传递的参数和返回值,可以是任意类型 

代码2:30min证明::给线程传递的参数和返回值,可以是任意类型 ,下面的例子是类类型

#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<string>
using namespace std;class Task{public:Task(int a,int b):_a(a),_b(b){}int Cal(){return _a+_b;}~Task() {}private:int _a;int _b;
};
class Result{public:Result(int result):_result(result){}int getresult(){return _result;}~Result(){}private:int _result;
};
void* routine(void* arg){Task*t = static_cast<Task*>(arg);sleep(1);Result* r = new Result(t->Cal());sleep(1);return r;
}int main(){pthread_t tid;Task* t = new Task(20,10);pthread_create(&tid,nullptr,routine,t);Result* ret = nullptr;pthread_join(tid,(void**)&ret);int n = ret->getresult();cout<<"子线程的返回值是:"<<n<<endl;
}

 

线程终止 

如果需要只终⽌某个线程⽽不终⽌整个进程,可以有三种⽅法:

1. 从线程函数return。这种⽅法对主线程不适⽤,从main函数return相当于调⽤exit。

2. 线程可以调⽤pthread_exit终⽌⾃⼰。

3. ⼀个线程可以调⽤pthread_cancel终⽌同⼀进程中的另⼀个线程。

 

pthread_exit:线程终止

功能:线程终⽌
原型:void pthread_exit(void *value_ptr);参数:value_ptr:value_ptr不要指向⼀个局部变量,就是指的一个变量
pthread_exit 的参数 value_ptr 是一个指向某个值的指针,该值将作为线程的返回值。这个返回值可以被主线程通过 pthread_join 获取。返回值:⽆返回值,跟进程⼀样,线程结束的时候⽆法返回到它的调⽤者(⾃⾝)

和return是等价的。 

线程等待 :pthread_join

为什么需要线程等待?

• 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。用来释放空间

• 创建新的线程不会复⽤刚才退出线程的地址空间。

功能:等待线程结束
原型int pthread_join(pthread_t thread, void **value_ptr);参数:thread:线程IDvalue_ptr:它指向⼀个指针,后者指向线程的返回值返回值:成功返回0;失败返回错误码

 进程以不同的方式终止,pthread_join得到的线程返回值是不一样的

调⽤该函数的线程将挂起等待,直到id为thread的线程终⽌。thread线程以不同的⽅法终⽌,通过 pthread_join得到的终⽌状态是不同的,总结如下:

1. 如果thread线程通过return返回,
value_ptr所指向的单元⾥存放的是thread线程函数的返回值。2. 如果thread线程被别的线程调⽤pthread_cancel异常终掉,
value_ptr所指向的单元⾥存放的是常 数PTHREAD_CANCELED。3. 如果thread线程是⾃⼰调⽤pthread_exit终⽌的,
value_ptr所指向的单元存放的是传给 pthread_exit的参数。4. 如果对thread线程的终⽌状态不感兴趣,可以传NULL给value_ptr参数。

pthread_cancel:取消线程 

参数:tid 

主线程取消新线程

取消的时候一定要保证:新线程已经启动 

 线程被取消,返回的结果是-1

解释:线程如果被取消退出的结果是-1

最推荐的还是return, 

线程分离 :pthread_detach(tid)

• 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进⾏pthread_join操作,否则 ⽆法释放资源,从⽽造成系统泄漏。

• 如果不关⼼线程的返回值,join是⼀种负担,这个时候,我们可以告诉系统,当线程退出时,⾃ 动释放线程资源。

如果主线程不想再关心新线程,而是当新线程结束的时候,让他自己释放??

设置新线程为分离状态
技术层面:  线程默认是需要被等待的,joinable。如果不想让主线程等待新线程
想让新线程结束之后,自己退出,设置为分离状态(!joinable or detach)  // todo
理解层面:线程分离,主分离新,新把自己分离。
分离的线程,依旧在进程的地址空间中,进程的所有资源,被分离的线程,依旧可以访问,可以操作。
主不等待新线程。
分离操作
如果线程被设置为分离状态,不需要进行join,join会失败!!

主线程设置分离

#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include <cstring>using namespace std;void* routine(void* arg){string name = static_cast<const char*>(arg);int cnt = 5;while(cnt--){cout<<"我是子线程,名字:"<<name<<endl;sleep(1);}
}int main(){pthread_t tid;pthread_create(&tid,nullptr,routine,(void*)"thread-1");//线程分离pthread_detach(tid);int cnt = 5;while(cnt--){cout<<"我是主线程"<<endl;sleep(1);}int n = pthread_join(tid,nullptr);if(n!=0){cout<<"pthread_join error"<<endl;}else{cout<<"pthread_join success"<<endl;}
}

 一个被分离的进程,调用join会失败。

pthread_join()失败,就会返回0。

线程自己设置分离

#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include <cstring>using namespace std;void* routine(void* arg){pthread_detach(pthread_self());string name = static_cast<const char*>(arg);int cnt = 5;while(cnt--){cout<<"我是子线程,名字:"<<name<<endl;sleep(1);}return nullptr;
}int main(){pthread_t tid;pthread_create(&tid,nullptr,routine,(void*)"thread-1");int cnt = 5;while(cnt--){cout<<"我是主线程"<<endl;sleep(1);}int n = pthread_join(tid,nullptr);if(n!=0){cout<<"pthread_join error"<<endl;}else{cout<<"pthread_join success"<<endl;}
}

 

创建多线程

#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <pthread.h>
#include <cstdio>
#include <cstring>创建多线程const int num = 10;void *routine(void *args){sleep(1);std::string name = static_cast<const char *>(args);delete (char*)args;int cnt = 5;while (cnt--){std::cout << "new线程名字: " << name << std::endl;sleep(1);}return nullptr;}int main(){// char id[64];多执行流访问同一份资源,有危险。std::vector<pthread_t> tids;for (int i = 0; i < num; i++){pthread_t tid;// bug??char *id = new char[64];//需要这么创建snprintf(id, 64, "thread-%d", i);int n = pthread_create(&tid, nullptr, routine, id);if (n == 0)tids.push_back(tid);elsecontinue;}for (int i = 0; i < num; i++){// 一个一个的等待int n = pthread_join(tids[i], nullptr);if (n == 0){std::cout << "等待新线程成功" << std::endl;}}return 0;}

 监控:while :; do ps -aL | head -1 && ps -aL | grep thread; sleep 1; done

注意点: 

(1)多执行流访问同一份资源,有危险。 

 char id[64];多执行流访问同一份资源,有危险

很大概率会引起,数据修改没导致结果不准确

(2) 为每一个线程自己创建一个,避免多执行流访问同一份资源

多执行流访问同一份资源

 

线程ID及进程地址空间布局

• pthread_create函数会产⽣⼀个线程ID,存放在第⼀个参数指向的地址中。
该线程ID和前⾯说的 线程ID不是⼀回事。• 前⾯讲的线程ID属于进程调度的范畴。因为线程是轻量级进程,
是操作系统调度器的最⼩单位, 所以需要⼀个数值来唯⼀表⽰该线程。• pthread_create函数第⼀个参数指向⼀个虚拟内存单元,
该内存单元的地址即为新创建线程的线 程ID,属于NPTL线程库的范畴。
线程库的后续操作,就是根据该线程ID来操作线程的。• 线程库NPTL提供了pthread_self函数,可以获得线程⾃⾝的ID:

动态库的链接类比:pthread库的链接 

过程:

磁盘里面的库文件,加载到物理内存里面,在把物理内存里面的库文件映射到mmap动态映射区域,或者可以叫做共享区。

这样进程自己的代码就可以访问到pthread库的内部函数或者数据

在库中对线程的管理: 

线程的概念是在库中维护的,在库内,就一定会存在多个被创建好的线程,库要不要管理线程呢?要!
先描述,在组织!!

创建线程描述符

mmap里面对线程的管理

mmap:动态映射区域
TCB:线程的属性
线程局部存储:暂时未知
线程栈:暂时未知
创建的返回值:
pthread_t tid:线程在库中,对应的管理快的虚拟地址。线程函数运行完,返回值,管理快还存在,
所以线程需要join,
join通过tid拿到线程管理快返回信息后,把管理快释放掉

(1)在一个线程中,运行完一个函数,那么,线程就会返回一个void*的值,*ret,但是管理线程的管理快并不会因为函数的执行完而消失,这里就会造成内存泄漏,所以我们需要pthread_join,来获取返回值,并且释放管理块的空间

(2)pthread_join工作流程:使用join,就可以得到该线程的返回值,*ret,然后释放管理块的空间,join的参数,tid拿到管理快的起始虚拟地址,就可以访问该管理快,&ret则用来接收返回值

(3) join:为什么要用二级指针来接受线程的返回值???便于修改值。单传不可修改值。

一个线程是怎么被创建的??? 

线程的一部分概念一部分在库里面实现:

pthread_create(&tid)创建线程时,首先会在pthread库里面创建一个线程的结构体struct_pthread(线程管理块)然后把id,返回给传入的tid,作为线程在pthread库的虚拟地址,后序好对线程进行操作。

一部分在PCB里面实现:

在内核中创建轻量级进程,通过clone来进行实现。(可以在看一遍,做更深了解)

例子:
我叫张三打饭
我是线程,维护信息(线程管理块)
张三给我打饭,根据信息给我打饭,张三是轻量级进程,去给我执行

总结: 

 

ID:线程控制块的起始地址

返回值:线程执行完,的返回值,被join回收

分离:joinable = 0线程分离

joinable!=0,线程不分离

joinable线程标记位

相关文章:

Linux:42线程控制lesson30

代码1&#xff1a;验证join可以去的线程执行完后的退出码/返回值 #include<iostream> #include<unistd.h> #include<pthread.h> #include<string> using namespace std;void* routine(void* arg){string name static_cast<const char*>(arg);i…...

配置 Apache 的 HTTPS

证书文件 文件名 作用 来源 example.com.key 服务器的私钥&#xff0c;用于加密和解密数据。 本地生成 -----BEGIN PRIVATE KEY----- MIIEowIBAAKCAQEAqp5c... -----END PRIVATE KEY----- example.com.csr Certificate Signing Request 证书签名请求文件&#xff0c;包…...

【Flutter高效开发】GetX指南:一文学会状态管理、路由与依赖注入

GetX是Flutter生态中最受欢迎的轻量级全能框架&#xff0c;以其简洁的API设计和卓越的性能著称。本文将带你全面掌握GetX的核心功能和使用技巧&#xff0c;提升你的Flutter开发效率。 一、GetX框架核心优势 1. 三位一体架构设计 模块功能传统方案对比状态管理响应式状态控制…...

第四节:核心概念高频题-Vue生命周期钩子变化

重命名&#xff1a;beforeDestroy→beforeUnmount&#xff0c;destroyed→unmounted 新增&#xff1a;onServerPrefetch&#xff08;SSR场景&#xff09; Vue 生命周期钩子变化详解&#xff08;Vue2 → Vue3&#xff09; 一、核心钩子重命名与语义优化 销毁阶段语义化升级 • …...

安全邮件系统的Maple实现详解

代码改进版&#xff1a; # # 安全邮件系统实现 - 结合DES和RSA加密 # 功能&#xff1a;实现安全的消息加密、签名和传输 # # -------------------------- # 第一部分&#xff1a;消息准备和加密 # --------------------------# 原始消息内容 message : "This is an atte…...

VTK-8.2.0源码编译(Cmake+VS2022+Qt5.12.12)

参考&#xff1a; 安装VTK 详细图文讲解CMake编译VTK&#xff0c;包含详细的编译环境版本 Visual Studio 2022 配置VTK9.3.0 VTK-8.2.0源码编译和初步使用(CmakeVS2015Qt5.14.2) 文章目录 下载编译编译环境介绍配置CMake信息BUILD_SHARED_LIBS控制生成的库是动态链接库&#xf…...

【playwright】学习--持续汇总

seleniumplaywrightselenium 需要结合其他自动化框架&#xff0c;比如pytest之后才能支持web自动化测试playwright 不需要其他自动化框架selenium库》webdriver》浏览器驱动playwright库》playwright driver》浏览器驱动 目录 安装playwright通过pip安装通过VScode安装 安装pla…...

深度解析算法之模拟

39.替换所有的问号 题目链接 给你一个仅包含小写英文字母和 ? 字符的字符串 s&#xff0c;请你将所有的 ? 转换为若干小写字母&#xff0c;使最终的字符串不包含任何 连续重复 的字符。 注意&#xff1a;你 不能 修改非 ? 字符。 题目测试用例保证 除 ? 字符 之外&#…...

leetcode刷题日记——插入区间

[ 题目描述 ]&#xff1a; [ 思路 ]&#xff1a; intervals 有序&#xff0c;需要将一个新的范围插入&#xff0c;然后进行整合方法一&#xff0c;将新的范围插入原 intervals 区间&#xff0c;然后使用 56 题的合并区间函数直接解决方法二&#xff0c; 找出能够包容 newInte…...

gbase8s存储学习一 rootdbs存储结构以及寻址分析

主要层次自下而上为 最小物理存储单元page &#xff0c;多个page 组成逻辑存储单元extent,多个extent 组成物理存储单元chunk ,而多个chunk组成逻辑存储单元dbspace&#xff0c;多个dbspace 组成一个数据库实例 在数据库初始化阶段会生成一个rootdbs表空间&#xff0c;该表空…...

学习设计模式《五》——工厂方法模式

一、基础概念 工厂方法模式的本质是【延迟到子类来选择实现】&#xff1b; 工厂方法模式的定义&#xff1a;定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类&#xff0c;FactoryMethod使一个类的实例化延迟到其子类 。 工厂方法模式的功能 序号说明0工厂方法模…...

如何将 Azure Active Directory (Azure AD) 作为 SAML IdP 对接到 Keycloak

✅ 一、在 Azure AD 创建 SAML 应用 &#x1f527; 1. 登录 Azure 门户 前往 https://portal.azure.com&#xff0c;使用管理员账号登录。 &#x1f4cc; 2. 创建企业应用&#xff08;Enterprise Application&#xff09; 左侧菜单进入 “企业应用程序”。点击 “新建应用程…...

OCR之身份证识别

前言 OCR身份证识别是光学字符识别技术在身份证领域的应用。通过扫描或拍照获取身份证图像&#xff0c;利用图像处理、深度学习等技术&#xff0c;自动提取姓名、性别、民族、出生日期、地址、身份证号等信息&#xff0c;可大幅提升信息录入效率&#xff0c;广泛应用于政务、金…...

JavaScript 渲染内容爬取:Puppeteer 高级技巧与实践

在现代网络应用中&#xff0c;动态网页内容的爬取一直是开发者面临的挑战之一。Puppeteer 作为一种强大的浏览器自动化工具&#xff0c;为这一问题提供了优雅的解决方案。本文将深入探讨 Puppeteer 的高级技巧&#xff0c;包括动态内容抓取、性能优化、反检测与伪装、复杂自动化…...

组织级项目管理OPM

组织级项目管理(Organizational Project Management, OPM)是一种系统化的管理方法,旨在通过整合项目组合、项目集和项目管理,确保组织的战略目标与项目执行的一致性,提升资源利用效率和项目成功率。以下是其核心内容与框架的详述: 一、组织级项目管理的定义与目标 定义 组…...

HTML与Web 性能优化:构建高速响应的现代网站

HTML 与 Web 性能优化&#xff1a;构建高速响应的现代网站 引言 随着互联网用户对网站加载速度期望的不断提高&#xff0c;前端性能优化已经成为现代 Web 开发的核心竞争力。据 Google 研究表明&#xff0c;页面加载时间每增加 1 秒&#xff0c;用户跳出率就会增加 32%。用户…...

模型 观测者效应

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。观察即影响&#xff0c;存在因注视而变。 1 观测者效应的应用 1.1 工业心理学—霍桑实验中的生产效率谜题 行业背景&#xff1a;20世纪20年代西方电气公司霍桑工厂&#xff0c;研究者试图通过优化照明…...

Ubuntu启动SMB(Samba)服务步骤

目录 1.基本的Samba服务器搭建流程主要分为四个步骤。 2.Samba工作流程&#xff1a; 3.解读主要配置文件smb.conf 4.开始安装Samba 5.检查Samba服务状态 6.创建Samba共享文件夹 7.配置Samba文件以及设置Samba用户密码 8.重启Samba服务器 9.关闭防火墙 10.Linux客户端…...

使用react的ant-design-pro框架写一个地图组件,可以搜索地图,可以点击地图获取点击的位置及经纬度

首先&#xff0c;先创建一个地图页面&#xff0c;用于显示地图组件&#xff0c;我是在pages文件中创建了一个mapSearch组件。 然后在routes.ts中注册页面。 {path: /mapSearch,name: mapSearch,icon: smile,component: ./mapSearch,}, 第三步就是使用高德地图来创建地图。 关键…...

【每日八股】复习计算机网络 Day4:TCP 协议的其他相关问题

文章目录 昨日内容复习已经建立了 TCP 连接&#xff0c;客户端突然出现故障怎么办&#xff1f;什么时候用长连接&#xff1f;短连接&#xff1f;TCP 的半连接队列与全连接队列&#xff1f;什么是 SYN 攻击&#xff1f;如何避免&#xff1f;TIME_WAIT 的作用&#xff1f;过多如何…...

Git远程操作与标签管理

目录 1.理解分布式版本控制系统 2.远程仓库 3.新建远程仓库 4.克隆远程仓库 5.向远程仓库推送 6.拉取远程仓库 7.配置Git 7.1.忽略特殊文件 7.2.给命令配置别名 8.标签管理 8.1.理解标签 8.2.创建标签 8.3.操作标签 1.理解分布式版本控制系统 Git是目前世界上…...

Element Plus消息通知体系深度解析:从基础到企业级实践

一、核心组件与技术定位 Element Plus的消息通知体系由三个核心组件构成&#xff1a;ElMessage&#xff08;全局提示&#xff09;、ElNotification&#xff08;通知弹窗&#xff09;和ElMessageBox&#xff08;交互式对话框&#xff09;。这套体系的设计目标是为开发者提供轻量…...

SpringCloud组件——Eureka

一.背景 1.问题提出 我们在一个父项目下写了两个子项目&#xff0c;需要两个子项目之间相互调用。我们可以发送HTTP请求来获取我们想要的资源&#xff0c;具体实现的方法有很多&#xff0c;可以用HttpURLConnection、HttpClient、Okhttp、 RestTemplate等。 举个例子&#x…...

[Godot] C#2D平台游戏基础移动和进阶跳跃代码

本文章给大家分享一下如何实现基本的移动和进阶的跳跃&#xff08;跳跃缓冲、可变跳跃、土狼时间&#xff09;以及相对应的重力代码&#xff0c;大家可以根据自己的需要自行修改 实现效果 场景搭建 因为Godot不像Unity&#xff0c;一个节点只能绑定一个脚本&#xff0c;所以我…...

C语言对n进制的处理

先看一道题目: 从键盘获取一个正整数,如果把它转为16进制的数字,那么它是一个几位数呢?如果把它转为28进制又是一个几位数呢? 在讲这个题目之前,我们先要了解进制转换 什么是进制转换&#xff1f; 简单来说&#xff0c;进制就是数位的表示方法。 十进制&#xff08;常用&am…...

rk3568main.cc解析

rk3568main.cc解析 前言解析总结前言 正点原子rk3568学习,rk官方RKNN_MODEL_ZOO文件中 rknn_model_zoo-main/examples/mobilenet/cpp/main.cc 从执行命令:./build-linux.sh -t rk3568 -a aarch64 -d mobilenet 到: cmake ../../examples/mobilenet/cpp \-DTARGET_SOC=rk3…...

【白雪讲堂】[特殊字符]内容战略地图|GEO优化框架下的内容全景布局

&#x1f4cd;内容战略地图&#xff5c;GEO优化框架下的内容全景布局 1️⃣ 顶层目标&#xff1a;GEO优化战略 目标关键词&#xff1a; 被AI理解&#xff08;AEO&#xff09; 被AI优先推荐&#xff08;GEO&#xff09; 在关键场景中被AI复读引用 2️⃣ 三大引擎逻辑&#x…...

S32K144学习(16)-Bootloader

1.什么是bootloader Bootloader&#xff08;引导加载程序&#xff09; 是存储在设备非易失性存储器&#xff08;如 ROM、Flash&#xff09;中的一段特殊程序&#xff0c;负责在设备上电后初始化硬件、加载操作系统&#xff08;OS&#xff09;或用户应用程序&#xff0c;并最终…...

反素数c++

先上代码 #include<bits/stdc.h> using namespace std; typedef long long ll; ll n; ll p[]{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; int maxd,maxval; void dfs(int pl,ll tmp,int num,int up){ if((num>maxd)||(nummaxd&&maxval>tmp)){ …...

C++ linux打包运行方案(cmake)

文章目录 背景动态库打包方案动态库转静态库动态库打到软件包中 运行 背景 使用C编写的一个小项目&#xff0c;需要打包成ubuntu下的可执行文件&#xff0c;方便分发给其他ubuntu执行&#xff0c;因为docker镜像方案过于臃肿&#xff0c;所以需要把项目的动态库都打在软件包中…...

JavaScript 渲染内容爬取实践:Puppeteer 进阶技巧

进一步探讨如何使用 Puppeteer 进行动态网页爬取&#xff0c;特别是如何等待页面元素加载完成、处理无限滚动加载、单页应用的路由变化以及监听接口等常见场景。 一、等待页面元素加载完成 在爬取动态网页时&#xff0c;确保页面元素完全加载是获取完整数据的关键。Puppeteer…...

AI数字人:元宇宙舞台上的闪耀新星(7/10)

摘要&#xff1a;AI数字人作为元宇宙核心角色&#xff0c;提升交互体验&#xff0c;推动内容生产变革&#xff0c;助力产业数字化转型。其应用场景涵盖虚拟社交、智能客服、教育、商业营销等&#xff0c;面临技术瓶颈与行业规范缺失等挑战&#xff0c;未来有望突破技术限制&…...

测试基础笔记第九天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、数据类型和约束1.数据类型2.约束3.主键4.不为空5.唯一6.默认值 二、数据库操作1.创建数据库2.使用数据库3.修改数据库4.删除数据库和查看所有数据库5.重点&…...

C++抽象基类定义与使用

在 C 中&#xff0c;抽象基类&#xff08;Abstract Base Class, ABC&#xff09; 是一种特殊的类&#xff0c;用于定义接口规范和约束派生类的行为。它通过纯虚函数&#xff08;Pure Virtual Function&#xff09;强制要求派生类实现特定功能&#xff0c;自身不能被实例化。以下…...

20.4 显示数据库数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的 20.4.1 设计时进行简单绑定 【例 20.22】【项目&#xff1a;code20-022】设计时关联数据库。 设计时设置DataGridView的DataSource属…...

PyTorch 多 GPU 入门:深入解析 nn.DataParallel 的工作原理与局限

当你发现单个 GPU 已经无法满足你训练庞大模型或处理海量数据的需求时&#xff0c;利用多 GPU 进行并行训练就成了自然的选择。PyTorch 提供了几种实现方式&#xff0c;其中 torch.nn.DataParallel (简称 DP) 因其使用的便捷性&#xff0c;常常是初学者接触多 GPU 训练的第一站…...

UDP协议理解

文章目录 UDP协议理解UDP 协议的特点&#xff1a;UDP协议图示UDP 的头部结构&#xff1a;UDP数据传输图示 UDP 的应用场景&#xff1a;TCP 与UDP对比UDP的传输丢包和顺序错乱问题&#xff08;了解&#xff09;丢包的解决方法&#xff1a;顺序错乱的解决方法&#xff1a;综合应用…...

微信小程序拖拽排序有效果图

效果图 .wxml <view class"container" style"--w:{{w}}px;" wx:if"{{location.length}}"><view class"container-item" wx:for"{{list}}" wx:key"index" data-index"{{index}}"style"--…...

算力网络的早期有关论文——自用笔记

2023年底至2024年初阅读有关论文的自用笔记&#xff0c;作为参考。 算力网络架构 https://baijiahao.baidu.com/s?id1727377583404975414&wfrspider&forpc think&note 是否可以和cpu进程调度联系。 目前&#xff1a;看一些综述深一步了解背景和发展现状,完善认…...

卷积神经网络基础(四)

今天我们继续学习各个激活函数层的实现过程。 目录 5.2 Sigmoid层 六、Affine/Softmax层实现 6.1 Affine层 6.2 批处理版本 5.2 Sigmoid层 sigmoid函数的表达式如下&#xff1a; 用计算图表示的话如下&#xff1a; 计算过程稍微有些复杂&#xff0c;且这里除了乘法和加法…...

【MySQL数据库】表的约束

目录 1&#xff0c;空属性 2&#xff0c;默认值 3&#xff0c;列描述 4&#xff0c;zerofill 5&#xff0c;主键primary key 6&#xff0c;自增长auto_increment 7&#xff0c;唯一键unique 8&#xff0c;外键foreign key 在MySQL中&#xff0c;表的约束是指用于插入的…...

网络威胁情报 | Friday Overtime Trooper

本文将分别从两个环境出发&#xff0c;以实践来体验利用威胁情报分析可疑文件的过程。 Friday Overtime 现在你是一位安全分析人员&#xff0c;正在美美等待周五过去&#xff0c;但就在即将下班之时意外发生了&#xff1a;你的客户发来求助&#xff0c;说他们发现了一些可疑文…...

GPIO(通用输入输出端口)详细介绍

一、基本概念 GPIO&#xff08;General - Purpose Input/Output&#xff09;即通用输入输出端口&#xff0c;是微控制器&#xff08;如 STM32 系列&#xff09;中非常重要的一个外设。它是一种软件可编程的引脚&#xff0c;用户能够通过编程来控制这些引脚的输入或输出状态。在…...

学习笔记——《Java面向对象程序设计》-继承

参考教材&#xff1a; Java面向对象程序设计&#xff08;第3版&#xff09;微课视频版 清华大学出版社 1、定义子类 class 子类名 extends 父类名{...... }如&#xff1a; class Student extends People{...... } &#xff08;1&#xff09;如果一个类的声明中没有extends关…...

基于javaweb的SpringBoot校园失物招领系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

什么事Nginx,及使用Nginx部署vue项目(非服务器Nginx压缩包版)

什么是 Nginx? Nginx(发音为 “engine-x”)是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。它以其高性能、高并发处理能力和低资源消耗而闻名。以下是 Nginx 的主要特性和用途: 主要特性 高性能和高并发 Nginx 能够处理大量并发连接,适合高…...

nodejs使用require导入npm包,开发依赖和生产依赖 ,全局安装

nodejs使用require导入npm包&#xff0c;开发依赖和生产依赖 &#xff0c;全局安装 ✅ 一、Node.js 中使用 require() 导入 npm 包 // 导入第三方包&#xff08;例如 axios&#xff09; const axios require(axios);// 使用 axios.get(https://api.example.com).then(res &g…...

CSS在线格式化 - 加菲工具

CSS在线格式化 打开网站 加菲工具 选择“CSS在线格式化” 或者直接访问 https://www.orcc.top/tools/css 输入CSS代码&#xff0c;点击左上角的“格式化”按钮 得到格式化后的结果...

图片转base64 - 加菲工具 - 在线转换

图片转base64 - 加菲工具 先进入“加菲工具” 网 打开 https://www.orcc.top&#xff0c; 选择 “图片转base64”功能 选择需要转换的图片 复制 点击“复制”按钮&#xff0c;即可复制转换好的base64编码数据&#xff0c;可以直接用于img标签。...

性能比拼: Redis vs Dragonfly

本内容是对知名性能评测博主 Anton Putra Redis vs Dragonfly Performance (Latency - Throughput - Saturation) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本视频中&#xff0c;我们将对比 Redis 和 Dragonfly。我们将观察 set 与 get 操作的延迟&#xff…...