学懂C++(三十):高级教程——深入解析 C++ Windows API 的多线程支持
引言
在现代应用程序中,多线程编程是实现高性能和高并发任务的关键手段。Windows 操作系统为开发者提供了一套强大的 API,用于创建和管理线程、同步任务,并优化线程性能。本文将深入探讨 C++ 中 Windows API 的多线程支持,详细介绍线程的创建与控制、线程优先级的设置、线程局部存储(TLS)、各种同步机制(如临界区、互斥体、信号量、事件)以及纤程(Fibers)的应用。
1. 线程的创建和控制
1.1 创建线程:CreateThread
CreateThread 是 Windows API 用于创建线程的函数。它允许程序在不同的并发路径上运行代码,从而提升应用程序的响应速度和处理能力。
示例:创建一个简单的线程
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout << "Thread is running." << std::endl;return 0;
}int main() {HANDLE hThread = CreateThread(nullptr, // 默认安全属性0, // 默认堆栈大小ThreadFunc, // 线程函数nullptr, // 线程函数参数0, // 默认创建标志nullptr // 不返回线程标识符);if (hThread) {WaitForSingleObject(hThread, INFINITE); // 等待线程完成CloseHandle(hThread); // 关闭线程句柄}return 0;
}
1.2 线程退出与终止:ExitThread 和 TerminateThread
ExitThread:用于安全地退出线程。TerminateThread:强制终止线程,但会导致资源泄漏,不推荐使用。
示例:使用 ExitThread 安全退出线程
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout << "Thread is running." << std::endl;ExitThread(0); // 安全退出线程
}int main() {HANDLE hThread = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {WaitForSingleObject(hThread, INFINITE); // 等待线程完成CloseHandle(hThread); // 关闭线程句柄}return 0;
}
示例:使用 TerminateThread 强制终止线程(不推荐)
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {while (true) {std::cout << "Thread is running." << std::endl;Sleep(1000);}return 0;
}int main() {HANDLE hThread = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {Sleep(3000); // 让线程运行一段时间TerminateThread(hThread, 0); // 强制终止线程(不推荐)CloseHandle(hThread); // 关闭线程句柄}return 0;
}
1.3 等待线程完成:WaitForSingleObject 和 WaitForMultipleObjects
WaitForSingleObject:用于等待单个线程或同步对象的信号。WaitForMultipleObjects:用于等待多个线程或同步对象的信号。
示例:使用 WaitForSingleObject 等待单个线程
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {Sleep(2000); // 模拟长时间运行的操作std::cout << "Thread completed." << std::endl;return 0;
}int main() {HANDLE hThread = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {std::cout << "Waiting for thread to complete..." << std::endl;WaitForSingleObject(hThread, INFINITE); // 等待线程完成std::cout << "Thread has completed." << std::endl;CloseHandle(hThread); // 关闭线程句柄}return 0;
}
示例:使用 WaitForMultipleObjects 等待多个线程
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {Sleep(1000); // 模拟操作std::cout << "Thread " << *(int*)lpParam << " completed." << std::endl;return 0;
}int main() {HANDLE hThreads[2];int threadParams[2] = { 1, 2 };for (int i = 0; i < 2; i++) {hThreads[i] = CreateThread(nullptr, 0, ThreadFunc, &threadParams[i], 0, nullptr);}std::cout << "Waiting for threads to complete..." << std::endl;WaitForMultipleObjects(2, hThreads, TRUE, INFINITE); // 等待所有线程完成for (int i = 0; i < 2; i++) {CloseHandle(hThreads[i]); // 关闭线程句柄}std::cout << "All threads have completed." << std::endl;return 0;
}
2. 线程优先级
Windows 提供了丰富的 API 来控制线程的优先级,以便更好地管理线程的执行顺序。
2.1 设置线程优先级:SetThreadPriority
SetThreadPriority 允许开发者根据线程的重要性来调整其优先级,从而影响调度器对线程的调度频率。
示例:设置线程的优先级
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout << "Thread is running at priority: " << GetThreadPriority(GetCurrentThread()) << std::endl;return 0;
}int main() {HANDLE hThread = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); // 设置线程优先级WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);}return 0;
}
2.2 获取线程优先级:GetThreadPriority
GetThreadPriority 用于获取当前线程的优先级,以便对线程的执行情况进行监控或调整。
示例:获取线程优先级
#include <windows.h>
#include <iostream>DWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout << "Thread is running at priority: " << GetThreadPriority(GetCurrentThread()) << std::endl;return 0;
}int main() {HANDLE hThread = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {int priority = GetThreadPriority(hThread);std::cout << "Initial thread priority: " << priority << std::endl;SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST); // 改变线程优先级priority = GetThreadPriority(hThread);std::cout << "Changed thread priority: " << priority << std::endl;WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);}return 0;
}
3. 线程局部存储(TLS)
线程局部存储(TLS)允许线程在其本地范围内存储和访问数据。每个线程都有独立的存储区域,不会与其他线程共享。
3.1 分配 TLS 索引:TlsAlloc
TlsAlloc 分配一个 TLS 索引,供后续在该索引上存取数据。
3.2 访问 TLS 数据:TlsGetValue 和 TlsSetValue
TlsGetValue:从指定的 TLS 索引获取数据。TlsSetValue:在指定的 TLS 索引上存储数据。
3.3 释放 TLS 索引:TlsFree
TlsFree 释放先前分配的 TLS 索引。
示例:使用 TLS 存储线程局部数据
#include <windows.h>
#include <iostream>DWORD tlsIndex;DWORD WINAPI ThreadFunc(LPVOID lpParam) {int localData = *(int*)lpParam; // 每个线程独立的数据TlsSetValue(tlsIndex, (LPVOID)&localData);int* pData = (int*)TlsGetValue(tlsIndex);std::cout << "Thread local data: " << *pData << std::endl;return 0;
}int main() {tlsIndex = TlsAlloc(); // 分配 TLS 索引if (tlsIndex == TLS_OUT_OF_INDEXES) {return 1;}int threadData[2] = { 10, 20 };HANDLE hThread1 = CreateThread(nullptr, 0, ThreadFunc, &threadData[0], 0, nullptr);HANDLE hThread2 = CreateThread(nullptr, 0, ThreadFunc, &threadData[1], 0, nullptr);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);CloseHandle(hThread1);CloseHandle(hThread2);TlsFree(tlsIndex); // 释放 TLS 索引return 0;
}
4. 同步机制
4.1 临界区(Critical Section)
临界区用于保护共享资源,防止多个线程同时访问同一资源。相比互斥体,临界区的性能更高,但只适用于单一进程内的线程同步。
InitializeCriticalSection:初始化临界区。EnterCriticalSection:进入临界区。LeaveCriticalSection:离开临界区。DeleteCriticalSection:删除临界区。
示例:使用临界区保护共享资源
#include <windows.h>
#include <iostream>CRITICAL_SECTION cs;
int counter = 0;DWORD WINAPI ThreadFunc(LPVOID lpParam) {for (int i = 0; i < 10000; ++i) {EnterCriticalSection(&cs);++counter;LeaveCriticalSection(&cs);}return 0;
}int main() {InitializeCriticalSection(&cs);HANDLE hThread1 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread2 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);std::cout << "Final counter value: " << counter << std::endl;CloseHandle(hThread1);CloseHandle(hThread2);DeleteCriticalSection(&cs);return 0;
}
4.2 互斥体(Mutex)
互斥体是用于多进程同步的对象。它比临界区更通用,但性能略低。
CreateMutex:创建或打开一个命名的互斥体对象。ReleaseMutex:释放互斥体。
示例:使用互斥体同步线程
#include <windows.h>
#include <iostream>HANDLE hMutex;DWORD WINAPI ThreadFunc(LPVOID lpParam) {WaitForSingleObject(hMutex, INFINITE); // 请求互斥体std::cout << "Thread running with mutex protection." << std::endl;Sleep(1000); // 模拟工作ReleaseMutex(hMutex); // 释放互斥体return 0;
}int main() {hMutex = CreateMutex(nullptr, FALSE, nullptr); // 创建互斥体HANDLE hThread1 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread2 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);std::cout << "Both threads have completed." << std::endl;CloseHandle(hThread1); // 关闭线程句柄CloseHandle(hThread2);CloseHandle(hMutex); // 关闭互斥体句柄return 0;
}
4.3 信号量(Semaphore)
信号量控制一组资源的访问权限,可以限制多个线程同时访问一个或多个资源。
CreateSemaphore:创建信号量对象。ReleaseSemaphore:释放信号量。
示例:使用信号量控制线程访问资源
#include <windows.h>
#include <iostream>HANDLE hSemaphore;DWORD WINAPI ThreadFunc(LPVOID lpParam) {WaitForSingleObject(hSemaphore, INFINITE); // 请求信号量std::cout << "Thread is accessing a limited resource." << std::endl;Sleep(1000); // 模拟工作ReleaseSemaphore(hSemaphore, 1, nullptr); // 释放信号量return 0;
}int main() {hSemaphore = CreateSemaphore(nullptr, 2, 2, nullptr); // 创建信号量,初始值和最大值均为2HANDLE hThread1 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread2 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread3 = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr); // 第三个线程将等待// 等待所有线程完成WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);WaitForSingleObject(hThread3, INFINITE);std::cout << "All threads have completed." << std::endl;CloseHandle(hThread1);CloseHandle(hThread2);CloseHandle(hThread3);CloseHandle(hSemaphore); // 关闭信号量句柄return 0;
}
4.4 事件(Event)
事件对象用于线程之间的信号传递,允许一个线程通知一个或多个线程某个事件的发生。
CreateEvent:创建事件对象。SetEvent:设置事件为信号状态。ResetEvent:将事件重置为非信号状态。
示例:使用事件同步线程
#include <windows.h>
#include <iostream>HANDLE hEvent;DWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout << "Thread waiting for event..." << std::endl;WaitForSingleObject(hEvent, INFINITE); // 等待事件被设置std::cout << "Thread proceeding after event!" << std::endl;return 0;
}int main() {hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); // 创建手动重置事件HANDLE hThread = CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {Sleep(2000); // 模拟一些工作std::cout << "Setting event." << std::endl;SetEvent(hEvent); // 释放线程WaitForSingleObject(hThread, INFINITE); // 等待线程完成CloseHandle(hThread);}CloseHandle(hEvent); // 关闭事件句柄return 0;
}
5. 纤程(Fibers)
纤程是比线程更轻量级的执行单元,允许程序在用户空间中管理调度。纤程的创建和切换比线程更快,适合某些特定的高性能应用。
5.1 纤程的基本操作
ConvertThreadToFiber:将当前线程转换为纤程。CreateFiber:创建纤程。SwitchToFiber:切换到指定的纤程。DeleteFiber:删除纤程。
示例:使用纤程
#include <windows.h>
#include <iostream>VOID CALLBACK FiberFunc(ULONG_PTR lpParam) {std::cout << "Fiber is running!" << std::endl;
}int main() {// 将主线程转换为纤程PVOID pFiber = ConvertThreadToFiber(nullptr);if (pFiber == nullptr) {std::cerr << "Failed to convert thread to fiber." << std::endl;return 1;}// 创建新的纤程PVOID pNewFiber = CreateFiber(0, FiberFunc, nullptr);if (pNewFiber == nullptr) {std::cerr << "Failed to create fiber." << std::endl;return 1;}// 切换到新的纤程SwitchToFiber(pNewFiber);// 切换回原纤程SwitchToFiber(pFiber);// 删除新创建的纤程DeleteFiber(pNewFiber);return 0;
}
6. 总结
通过以上内容,我们详细展示了 C++ 中 Windows API 的多线程支持,包括线程的创建、控制、优先级管理、线程局部存储、各种同步机制(临界区、互斥体、信号量、事件)以及纤程的使用。每个示例都展示了如何使用相关的 Windows API,帮助你加深理解和掌握多线程编程的技巧。希望这些示例能够帮助你在开发高性能和高并发的应用程序时更得心应手。通过掌握这些技术,开发者能够构建高效、稳定的多线程应用,充分利用现代硬件的并发能力,提升应用程序的性能。希望本文能够为 C++ 开发者提供有益的指导和实践经验,助力提升在 Windows 平台下的多线程编程能力。
上一篇:学懂C++(二十九):高级教程——深入解析 C++ 异步任务和 Futures:std::future、
下一篇:学懂C++(三十一):高级教程——深入详解C++高级多线程编程技术之锁优化与替代
相关文章:
学懂C++(三十):高级教程——深入解析 C++ Windows API 的多线程支持
引言 在现代应用程序中,多线程编程是实现高性能和高并发任务的关键手段。Windows 操作系统为开发者提供了一套强大的 API,用于创建和管理线程、同步任务,并优化线程性能。本文将深入探讨 C 中 Windows API 的多线程支持,详细介绍线…...
苹果笔记本电脑可以玩steam游戏吗 MacBook支持玩steam游戏吗 在Steam上玩黑神话悟空3A大作 苹果Mac怎么下载steam
游戏是生活的润滑剂,越来越多的用户开始关注Mac平台上可玩的游戏。幸运的是,Steam作为最大的数字发行平台之一,提供了大量适用于Mac操作系统的游戏。无论你是喜欢策略、冒险还是射击类游戏,都能在Steam上找到适合自己Mac设备玩耍的…...
海康摄像头(测温型)桌面客户端开发分享
分享一个自己开发的用于企业特殊场景下温度监控告警的一个桌面应用。 关键功能: 1.支持海康摄像头; 2.支持多路视频预览,多通道画面选择预览,支持视频画面回放与下载; 3.支持自动探测摄像头功能,若具备…...
骑行耳机哪个品牌性价比高?精选五大畅销骑行耳机推荐!
骨传导耳机凭借不入耳佩戴更舒适、健康等特定在短时间内迅速风靡骑行圈,其独特的设计不仅让骑行者在享受音乐的同时保持对周围环境的警觉,还因其非入耳式的佩戴方式,有效避免了长时间骑行对耳朵的压迫与不适。它不仅能够激发骑行时的激情与动…...
libcurl8.9.1 上传json
在postman中 PUT----》body----》raw----》json 结构体定义: #define MAX_ARRAY_SIZE 5*1024*1024struct SMART_DATA_CACHE {char* buf;long dwTotalLen;SMART_DATA_CACHE(){dwTotalLen 0;buf nullptr;while (!buf) {try {buf new char[MAX_ARRAY_SIZE];}c…...
什么是暗水印?企业暗水印如何实施?企业保护利器
“明察秋毫之末,而不见舆薪。” 此言道出了观察之细致入微,却也隐含了信息泄露之隐忧。 在今日之数字时代,信息如潮水般汹涌,而电脑屏幕作为信息展示的重要窗口,其安全性亦成为众人关注的焦点。 当谈及监控电脑屏幕以…...
Qt 系统相关 - 文件
目录 1. 文件概述 2. 输入输出设备类 3. 文件读写类 4. 文件和目录信息类 1. 文件概述 文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。 Qt 提供了很多关于文件的类,通过这些类能够对文件系统进行操作&#x…...
Android Toast居中显示方法二
Android Toast居中显示方法一请看 Android Toast设置居中显示方法一-CSDN博客 下面来讲讲第二种方法: Toast toast Toast.makeText(MainActivity.this, "my toast", Toast.LENGTH_SHORT);LinearLayout.LayoutParams layoutParams new LinearLayout.Lay…...
Vue启动时报异常 ‘error:03000086:digital envelope routines::initialization error‘
问题描述 启动Vue项目时,突发报如下异常: opensslErrorStack: [error:03000086:digital envelope routines::initialization error,error:0308010C:digital envelope routines::unsupported],library: digital envelope routines,reason: unsupported,…...
C#委托—马工教你轻松玩转委托
前言 在C#中有一个小白谈之色变的知识点叫委托,很多学了一两年C#的还不知道委托究竟是什么东西,本文就来帮你彻底解开解惑,从此委托就是小儿科! 1、委托的本质 委托也是一种类型,大家知道所有的类型一定对应一种数据…...
当下最强的 AI art 生成模型 Stable Diffusion 最全面介绍
目录 模型生成效果展示(prompt 全公开) 如何注册 Stable Diffusion 使用 SD(dreamstudio.ai )的收费标注如何 SD 提供哪些参数可以设置 如何使用种子来改进一张作品 我用 SD 创作的图片著作权如何归属,可以拿来商…...
NPM 使用教程:从入门到精通
NPM 使用教程:从入门到精通 1. 引言 什么是 NPM? NPM (Node Package Manager) 是 JavaScript 的包管理工具,也是世界上最大的开源库生态系统。它帮助开发者轻松地管理项目的依赖、安装和分享包。NPM 与 Node.js 紧密结合,并在开…...
基于ssm+vue+uniapp的停车场小程序的设计与实现
开发语言:Java框架:ssmuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:M…...
C语言典型例题37
《C程序设计教程(第四版)——谭浩强》 例题3.5 按照按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分,C等为 60~69分,D等在60分以下,成绩的等级从键盘输入 代码: //…...
二自由度机械臂软件系统(三)ros2_control硬件底层插件
ros2_control实现了两个功能,一个是控制算法插件即控制的实现,另一个是底层插件即跟硬件通信的功能。 参考资料:https://zhuanlan.zhihu.com/p/682574842 1、创建功能包 ros2 pkg create --build-type ament_cmake robot_control_test在sr…...
24.8.9.11数据结构|链栈和队列
链栈 1、理解 实际上是一个仅在表头进行操作的单链表,头指针指向栈顶结点或头结点,以下恋栈均指带头结点的链栈. 2、 基本操作 1、定义结构:节点含有数据域和指针域 2、初始化操作:建立一个带头结点的空栈 3、取栈顶元素操作:取出栈的栈顶元…...
StarSpider:一款高效的网络爬虫框架解析与实战
文章目录 引言官网链接StarSpider 原理简介基础使用1. 添加依赖2. 编写PageProcessor3. 启动爬虫 高级使用1. 分布式抓取2. 自定义下载器3. 深度定制 优点结语 引言 在大数据时代,数据成为了推动业务增长和创新的关键。网络爬虫作为数据获取的重要手段之一…...
LVS详细解析及其NAT模式与DR模式部署(理论+实验全方位指导)
目录 1. 集群 2. 分布式系统 3. 集群与分布式的比较 4.通俗的解释 集群 分布式系统 总结 LVS(Linux Virtual Server)简介 LVS专业术语 工作原理 LVS调度算法 静态调度算法 动态调度算法 ipvsadm脑图 NAT模式集群 LVS的配置 在LVS主机内打开…...
负载均衡相关概念介绍(一)
负载均衡(Load Balance)是集群技术的一种重要应用,旨在将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,从而提高系统的并发处理能力、增加吞吐量、加强网络处理能力,并提供故障转移以…...
二叉树详解(1)
文章目录 目录1. 树的概念及结构1.1 树的相关概念1.2 树的表示1.3 树在实际中的运用(表示文件系统的目录树结构) 2. 二叉树的概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的存储结构 3. 二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
