C++windows内核编程笔记day13 进程、线程与信号量

简介: Windows进程 进程是一个容器,包含程序执行需要的代码、数据、资源等信息, windows进程的特点:每个进程都有自己的ID号每个进程都有自己的地址空间,进程之间无法访问对方的地址空间。

Windows进程

进程是一个容器,包含程序执行需要的代码、数据、资源等信息,
windows进程的特点:
每个进程都有自己的ID号
每个进程都有自己的地址空间,进程之间无法访问对方的地址空间。
每个进程都有自己的安全属性
每个进程至少包含一个线程。
获取和释放环境信息
GetEnvironmentStrings
FreeEnvironmentStrings
获取或设置 本程序的环境变量
GetEnvironmentVariable
SetEnvironmentVariable
示例:
char* env=(char*) GetEnvironmentStrings();
char* env2=env;
while(env2[0])
{
printf("%s\n",env2);
env2=env2+strlen(env2)+1;
}
FreeEnvironmentStrings(env);
SetEnvironmentVariable("abc","100");
char buf[10]={0};
GetEnvironmentVariable("abc",buf,256);
printf("%s\n",buf);


进程信息
1、进程ID
DWORD pid= GetCurrentProcessId();
2、进程句柄
HANDLE hpro=GetCurrentProcess();
3、启动进程
BOOL CreateProcess(
  LPCTSTR lpApplicationName,//应用程序名称
  LPTSTR lpCommandLine,//命令行参数
  LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // SD
  BOOL bInheritHandles,//能否被子进程使用
  DWORD dwCreationFlags,//创建方式
  LPVOID lpEnvironment,//环境信息
  LPCTSTR lpCurrentDirectory,//当前目录
  LPSTARTUPINFO lpStartupInfo,//返回的:起始信息
  LPPROCESS_INFORMATION lpProcessInformation //返回的:进程信息
);
示例:
STARTUPINFO stinfo={0};
PROCESS_INFORMATION pi={0};
CreateProcess("C:/Windows/System32/calc.exe",0,NULL,NULL,TRUE,0,NULL,NULL,
&stinfo,&pi);
WaitForSingleObject(pi.hProcess,INFINITE);//等待信号(一般是进程结束才有信号)
printf("Processid=%d,handle=%d\n",pi.dwProcessId,pi.hProcess);
退出本进程
VOID ExitProcess(  UINT uExitCode//退出码
);
退出任意进程
BOOL TerminateProcess(  HANDLE hProcess, // handle to the process
  UINT uExitCode   // exit code for the process
);


通过进程ID获取进程句柄
HANDLE OpenProcess(
DWORD dwDesiredAccess,  // access flag
BOOL bInheritHandle,// handle inheritance option
 DWORD dwProcessId// process identifier
);
获取和关闭进程示例(进程ID为32):
HANDLE calc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,32);
TerminateProcess(calc,-1);
进程间的等候,等候 进程/线程 信号到来
(一般是进程结束才有信号)
DWORD WaitForSingleObject(
HANDLE hHandle,        // handle to object
DWORD dwMilliseconds   // time-out interval
);

windows线程

windows线程是可以执行的代码实例。系统是以线程为单位调度程序。
windows线程特点:
线程都有Id
线程具有自己的安全属性
线程有什么的内存栈
线程都有自己的寄存器信息
进程多任务:每个进程都使用私有的地址空间。
线程多任务:进程内多个线程使用同一个地址空间。
线程处理函数:
DWORD WINAPI ThreadProc(
LPVOID lpParameter   // thread data
);
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,// SD
SIZE_T dwStackSize, // 线程栈大小(默认1M)
LPTHREAD_START_ROUTINE lpStartAddress, // 线程处理函数
LPVOID lpParameter,  //传给线程处理函数的参数
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId //返回值:线程ID
);
dwCreationFlags:
0-创建之后立即执行
CREATE_SUSPENDED-创建之后挂起,不立即执行


//结束线程,与结束进程用法一样
TerminateThread(...)
ExitThread(...);
CloseHandle()//关闭线程句柄,不是结束线程
可用WaitForSingleObject()等候线程结束
挂起线程
DWORD SuspendThread(  HANDLE hThread   // handle to thread);
恢复线程
DWORD ResumeThread(  HANDLE hThread   // handle to thread);
示例:
DWORD CALLBACK TestProc1(LPVOID param)
{
char*txt=(char*)param;
while(1)
{
printf("%s\n",txt);
Sleep(1000);
}
}
DWORD CALLBACK TestProc2(LPVOID param)
{
char*txt=(char*)param;
while(1)
{
printf("%s\n",txt);
Sleep(1000);
}
}
void Thread()
{
DWORD tid=0;
char *txt="*************************";
HANDLE hthread1=CreateThread(NULL,0,TestProc1,txt,
0,&tid);
char *txt2="————————————";
HANDLE hthread2=CreateThread(NULL,0,TestProc2,txt2,
CREATE_SUSPENDED,&tid);
getchar();
SuspendThread(hthread1);//挂起
ResumeThread(hthread2);//恢复
}
获取线程ID和句柄,与进程操作类似:
GetCurrentThreadId
GetCurrentThread

OpenThread



进程示例代码:

// WinEnv.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<STDIO.H>
#include<WINDOWS.H>
void winProc()
{
	char* env=(char*) GetEnvironmentStrings();
	char* env2=env;
	while(env2[0])
	{
		printf("%s\n",env2);
		env2=env2+strlen(env2)+1;
	}
	FreeEnvironmentStrings(env);
	SetEnvironmentVariable("abc","100");
	char buf[10]={0};
	GetEnvironmentVariable("abc",buf,256);
	printf("%s\n",buf);
	DWORD pid= GetCurrentProcessId();
	HANDLE hpro=GetCurrentProcess();

	
}
void CreateProc()
{
	STARTUPINFO stinfo={0};
	PROCESS_INFORMATION pi={0};
	CreateProcess("C:/Windows/System32/calc.exe",0,NULL,NULL,TRUE,0,NULL,NULL,
		&stinfo,&pi);
	WaitForSingleObject(pi.hProcess,INFINITE);//等待信号(一般是进程结束才有信号)
	printf("Processid=%d,handle=%d\n",pi.dwProcessId,pi.hProcess);
}
void KillProc()
{
	HANDLE calc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,32);
	TerminateProcess(calc,-1);
}

int main(int argc, char* argv[])
{
	//winProc();
	CreateProc();
	//KillProc();
	return 0;
}


线程与信号量使用示例(信号量是一种线程同步技术):

// winThread.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<stdio.h>
#include<windows.h>
char g_txt[256];
char g_txt2[256];
CRITICAL_SECTION cs={0};

HANDLE g_hSem=0;
DWORD CALLBACK PrintProc(LPVOID param)
{
	char buf[10]={0};
	while(1)
	{
		
		WaitForSingleObject(g_hSem,INFINITE);//有信号才执行
		ZeroMemory(buf,sizeof(buf));
		GetEnvironmentVariable("exit",buf,sizeof(buf));
		if(strcmp(buf,"1")==0) break;
		printf("**************************\n");
		
	}
	return 0;
}
/*
DWORD CALLBACK CtrlProc(LPVOID param)
{
	int i=0;
	while(1)
	{
		SetEvent(g_hevent);//发一个信号
		Sleep(1000);
		i++;
		if(i==1000) break;
	}
	return 0;
}
*/
void Thread()
{
	DWORD tid=0;
	char *txt="**************************";
	HANDLE hthread1=CreateThread(NULL,0,PrintProc,txt,
		0,&tid);
	/*
	//char *txt2="—————————————";
	//HANDLE hthread2=CreateThread(NULL,0,CtrlProc,txt2,
	//	0,&tid);
	//HANDLE ht[2]={0};
	//ht[0]=hthread1;
	//ht[1]=hthread2;
	//WaitForMultipleObjects(2,ht,TRUE,INFINITE);
	*/
	SetEnvironmentVariable("exit","0");
	while(1)
	{
		char c=getchar();
		if(c=='\0'||c=='\n') continue;
		int count=c-'0';
		printf("count1=%d  \n",count);
		if(count>=0&& count<=9)
		{
			printf("count2=%d  \n",count);
			ReleaseSemaphore(g_hSem,count,NULL);//重新设置成5次
		}
		else if(c=='e'|| c=='E')
		{
			SetEnvironmentVariable("exit","1");
			ReleaseSemaphore(g_hSem,1,NULL);//重新设置成5次
			break;
		}
		
	}

	WaitForSingleObject(hthread1,INFINITE);
	printf("wait over!\n");
	CloseHandle(hthread1);
	//CloseHandle(hthread2);
}

int main(int argc, char* argv[])
{
	g_hSem=CreateSemaphore(NULL,3,10,"s1");
	Thread();
	CloseHandle(g_hSem);
	return 0;
}





相关文章
|
3天前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
32 17
|
12天前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
48 26
|
2月前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
218 2
|
3月前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
2月前
|
缓存 Java 调度
多线程编程核心:上下文切换深度解析
在现代计算机系统中,多线程编程已成为提高程序性能和响应速度的关键技术。然而,多线程编程中一个不可避免的概念就是上下文切换(Context Switching)。本文将深入探讨上下文切换的概念、原因、影响以及优化策略,帮助你在工作和学习中深入理解这一技术干货。
58 10
|
2月前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
2月前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
71 3
|
2月前
|
算法 调度 开发者
多线程编程核心:上下文切换深度解析
在多线程编程中,上下文切换是一个至关重要的概念,它直接影响到程序的性能和响应速度。本文将深入探讨上下文切换的含义、原因、影响以及如何优化,帮助你在工作和学习中更好地理解和应用多线程技术。
54 4
|
2月前
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
3月前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
93 1

热门文章

最新文章