学习记录(2022年四月份)
Posted 水澹澹兮生烟.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习记录(2022年四月份)相关的知识,希望对你有一定的参考价值。
目录
2022_04_01
1.实现客户端服务端持续进行交互
2.如何让一个服务程序启动多个服务
LPSERVICE_MAIN_FUNCTION 类型定义指向此回调函数的指针。服务的入口点
3.再将程序打包后,在没有VS环境下会报错:丢失VCRVNTIME140.dll
解决:a.安装需要的运行时库
b.将需要的.dll文件放入.exe文件的目录下
2022_04_07
1.windows下守护进程的实现
2.
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow);
APIENTRY是WINAPI的别名。WINAPI 本身是用于 Windows API 调用的调用约定类型的定义,即 stdcall。基本上,这是向编译器解释在调用此函数时如何处理堆栈和参数。
它只是WINAPI的一个#define,WINAPI是Windows入口点的标准装饰。
#define APIENTRY WINAPI
2022_04_09
1.CreateProcessAsUserA 函数
BOOL CreateProcessAsUserA(
[in, optional] HANDLE hToken,
[in, optional] LPCSTR lpApplicationName,
[in, out, optional] LPSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCSTR lpCurrentDirectory,
[in] LPSTARTUPINFOA lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
创建进程及其主线程,通常调用此函数必须要有SE_INCREASE_QUOTA_NAME特权。
2022_04_11
1.进程互斥量问题
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);
创建互斥量用来同步,如果一个线程获得互斥体,则要获取该互斥体的第二个线程将会被挂起,直到第一个线程释放该互斥体。
如果有同名程序运行,则需要通过GetLastError()得到错误代码ERROR_ALREADY_EXISTS,他判断了 当文件已经存在,则无法再次创建。
HANDLE hMutex = CreateMutex(NULL, TRUE, AGSDAEMON_MUTEX);//创建一个互斥量
if (hMutex != NULL && ERROR_ALREADY_EXISTS == GetLastError())
//进程已存在
return 0;
2022_04_13
1.
2022_04_14
1.注册的服务进程与控制台进程之间的权限问题
需要两个不同权限的进程进行通信需要对其进行权限的提升,
2.使用命名管道进行通信时,ReadFile函数阻塞如何退出问题
3.使用内存映射对象步骤:
- CreateFile()创建一个或打开一个文件内核对象,该对象标识了我们想要用作内存映射文件的那个磁盘文件。
- CreateFileMappingA()创建一个文件映射内核对象,来告诉哦我们系统文件的大小以及我们打算如何访问文件。
- 告诉系统把文件映射对象的部分或者全部映射到进程地址空间中。
- 使用完内存映射对象后告诉系统从进程地址空间中取消对文件映射内核对象的映射。
- 关闭文件映射内核对象。
- 关闭文件内核对象。
4.如果客户端两个线程,一个线程先于另一个线程连接到客户端的管道上,另一个线程此时也要在管道中写入数据,会发生什么?
2022_04_18
1.critical_section类
临界区又称为关键代码段,指的是一小段代码在代码执行前,需要独占一些资源。线程中通常见多线程同步时访问的某个资源作为临界区,此时需要定义一个CRETICAL_SECTION变量,然后调用InitiallizeCriticalSection函数对变量进行初始化。
//对变量初始化
InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection );
/*lpCriticalSection:一个CRITICAL_SECTION结构指针,表示用于初始化临界区;
InitializeCriticalSection:他在内部设置了CRITICAL_SECTION结构的某些成员变量,所以他不会失败
*/
//将某一段代码定义为临界区
VOID WINAPI EnterCriticalSection(__inout LPCRITICAL_SECTION lpCriticalSection);
/*此函数作用是判断是否有现成访问临界区资源,如果有线程访问资源,则进入等待状态,知道没有线程访问。*/
//释放资源函数
void WINAPI LeaveCriticalSection( _Inout_LPCRITICAL_SECTION lpCriticalSection);
//释放CRITICAL_SECTION结构体指针
void WINAPI DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
返回值:对临界区的引用
其实CRITICAL_SECTION并非锁定了资源,他其实是不能够锁定资源的,她能够完成的功能,是同步不同线程的代码段。举个栗子,当线程执行了EnterCritialSection之后,cs里面的信息被修改,指明哪个线程使用了他,而此时并没有任何资源被锁定,不管什么资源,其他线程都是还可以进行访问的(当然,执行的结构可能是错误的)。只不过在这个线程执行EnterCritialSection之前你,其他线程执行EnterCritialSection语句时,会处于等待状态,相当于线程被挂起,这样就起到了保护作用。
由于CRITICAL_SECTION是这样发挥作用的,因此必须将每个线程中访问共享资源的语句放在EnterCritialSection和LeaveCritialSection之间。
2. GetModuleFileNameA()函数
检索包含指定模块的文件的完全限定路径。
DWORD GetModuleFileNameA(
[in, optional] HMODULE hModule,//正在请求其路径的已加载模块句柄如果此参数为空,则GetModuleFileName将检索当前进程的可执行文件路径。
[out] LPSTR lpFilename,//指向接收模块的完全限定路径的缓冲区的指针
[in] DWORD nSize//文件名缓冲区的大小
);
//返回值:如果函数成功,则返回值是复制到缓冲区的字符串的长度,函数失败,则返回0.
3.一些函数的学习
- SetCurrentDirectoryA()函数
切换当前进程当前工作目录,设置但钱路径,然后就可以一向对路径访问一些所运行程序相关的文件,不需要绝对路径。
BOOL SetCurrentDirectory(
[in] LPCTSTR lpPathName
);
/*
新的当前目录的路径。此参数可以指定相对路径或完整路径。在任一情况下,都会计算指定目录的完整路径并将其存储为当前目录。
*/
- InitializeCriticalSection()函数
void InitializeCriticalSection(
[out] LPCRITICAL_SECTION lpCriticalSection //指向关键部分对象的指针
);
此函数初始化一个临界区对象,单个进程的线程可以使用一个互斥同步临界对象。虽然对线程将获取的临界区所有权的顺序没有保证,因而该系统能公平对待每一个线程。
4.对线程中用来确保同一时刻只有一个线程操作被保护数据
//初始化临界区
InitializeCriticalSection(cs)&;
//进入临界区
EnterCriticalSection(&cs);
//操作数据
asa += 2;//所有访问asa变量的程序都需要这样写enter...leave...
//离开临界区
LeaveCriticalSetion(&cs);
//删除临界区
DeleteCriticalSection(&cs);
多线程操作相同数据的时候,一般是要按照顺序进行访问的,否则会引起数据的错乱,无法控制数据,变成随机量,这样就要使用到互斥操作。
2022_04_19
1.手动生成sqlite3.lib文件
在vs命令提示符下生成。
cd D:\\sqlite\\sqlite
lib /def:sqlite3.def
2022_04_21
1.error LNK2019: 无法解析的外部符号 ___iob_func,该符号在函数 % 中被引用
报错大都是找不到外部符号__iob
,原因是VS2010上使用了VC6编译的DLL,或者使用VS2015用的VS2010编译的静态库,其实__iob_func
和__iob
都是用来定义stdin,stdout,stderr
,只是不同的VC版本实现方式不同。我们只需要在自己的代码中加入如下代码:
/*
* 当libjpeg-turbo为vs2010编译时,vs2015下静态链接libjpeg-turbo会链接出错:找不到__iob_func,
* 增加__iob_func到__acrt_iob_func的转换函数解决此问题,
* 当libjpeg-turbo用vs2015编译时,不需要此补丁文件
*/
#if _MSC_VER>=1900
#include "stdio.h"
_ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned);
#ifdef __cplusplus
extern "C"
#endif
FILE* __cdecl __iob_func(unsigned i)
return __acrt_iob_func(i);
#endif /* _MSC_VER>=1900 */
2022_04_24
1. error C1853: “Debug\\authorization.pch”预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
出现错误的原因是因为混合了c与c++文件,因而不能共用一个预编译头文件。
2022_04_25
1.将byte类型的数组转换成16进制数组
string bytesToHexString( unsigned char* bytes, const int length)
if (bytes == NULL)
return "";
string buff;
const int len = length;
for (int j = 0; j < len; j++)
/*if ((bytes[j] & 0xff) < 16)
buff.append("0");
*/
int high = bytes[j] / 16, low = bytes[j] % 16;
buff += (high<10) ? ('0' + high) : ('A' + high - 10);
buff += (low<10) ? ('0' + low) : ('A' + low - 10);
return buff;
2022_04_26
1.复习一下txt文件的读写操作
- fstream中提供的三各类,实现C++对文件的操作
ifstream | 从已有文件读取 |
ofstream | 向文件写内容 |
fstream | 打开文件供读写 |
- 文件打开模式
ios::in
只读 ios::out
2022_04_28
1.实现两个时间戳之间的差值:
int main()
DWORD time_start, time_now;
time_start = GetTickCount();//从授权码中获取
Sleep(9000);
time_now = GetTickCount(); //获取当前时间
//计算剩余时间
int ns = 1000;//一秒多少毫秒
int nm = 60 * ns;//一分钟多少毫秒
int nh = 60 * nm;//一小时多少毫秒
int nd = 24 * nh;//一天多少毫秒
long left = time_now - time_start;
int d = (int)(left / nd);//天数
left = left % nd;
int h = (int)(left / nh);
left = left % nh;
int m = (int)(left / nm);
left = left % nm;
int s = (int)(left / ns);
left = left % ns;
cout << d << "天-" << h << "小时-" << m << "分钟-" << s<<"秒" << endl;
return 0;
2022_04_29
1.win10下获取硬盘序列号
C:\\Users\\pc2>wmic diskdrive get serialnumber
SerialNumber
0023_0356_3009_9792.
S3RZNF0K845722
以上是关于学习记录(2022年四月份)的主要内容,如果未能解决你的问题,请参考以下文章