五华建设银行网站,软件ui设计网站,怎样申请建网站,修改网站模板目录 一、创建线程
CreateThread函数#xff1a; 下面是示例#xff1a;
编辑
ThreadProc函数解释#xff1a; DWORD的本质是 unsigned long PVOID的本质是 void*
二、线程的终止
1.WaitForSingleObject()函数#xff1a;
示例如下#xff1a; 2.ExitThread()函…目录 一、创建线程
CreateThread函数 下面是示例
编辑
ThreadProc函数解释 DWORD的本质是 unsigned long PVOID的本质是 void*
二、线程的终止
1.WaitForSingleObject()函数
示例如下 2.ExitThread()函数:
示例如下
3.TerminateThread()函数:
4.CloseHandle()函数: 5.正常return 0;
三、线程的恢复与挂起
1.挂起线程
①SuspendedThread()函数:
示例如下 ②CreateThread()的第五个参数设为CEREATE_SUSPENDED 四、线程的优先级 一、创建线程
CreateThread函数 该函数用于创建一个新的线程并在其上运行指定的函数其返回值是HANDLE类型句柄原型如下
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId); 第一个参数: 指向SECURITY_ATTRIBUTES形态的结构的指针,表示线程内核对象的安全属性 windows 98忽略该参数windows NT中设为NULL表示使用默认安全属性 第二个参数: 初始该线程的堆栈大小以字节为单位默认为0即使用默认大小1MB在任何情况下OS会动态延长堆栈大小 第三个参数: 是一个指向线程函数的指针。线程将从此函数的入口点开始执行。 函数名称无限制但必须是以下形式声明 DWORD WINAPI ThreadProc(PVOID pParam); 第四个参数 传递给线程函数第三个函数的参数的参数是一个指针类型。 第五个参数 线程的创建标志通常设置为0即可可选参数如下 0或CREATE_SUSPENDED默认值创建线程后立即执行线程函数。 CREATE_SUSPENDED创建线程后暂停线程的执行需要通过ResumeThread激活线程。 CREATE_DETACHED创建一个分离的线程不需要手动释放线程资源。 STACK_SIZE_PARAM_IS_A_RESERVATION将dwStackSize参数解释为堆栈的保留大小。 CREATE_NEW_CONSOLE创建一个新的控制台窗口使线程在独立的控制台环境中运行。 CREATE_UNICODE_ENVIRONMENT使用Unicode字符集解析环境字符串。 第六个参数 一个指向DWORD类型的指针用于接收新线程的标识符ID 将返回线程的ID号传入NULL表示不需要返回该线程ID号 下面是示例
#include iostream
#include windows.h //调用windows API的头文件
using namespace std;//线程函数格式固定
DWORD WINAPI ThreadProc(PVOID lp){//线程的主体//…………return 0;
};int main()
{CreateThread(NULL, 0, ThreadProc, NULL, 0, 0);return 0;
} ThreadProc函数解释 该函数即线程入口ThreadProc 和 lp一样, 名字随意, ThreadProc函数本身作为CreateThread函数的第三个参数该函数参数由CreateThread函数的第四个参数传入 DWORD的本质是 unsigned long PVOID的本质是 void* 注意在多线程环境中全局变量是所有线程共享的这意味着多个线程可以同时访问和修改这些全局变量。因为线程是并发的所以当一个线程在执行过程中修改了全局变量的值时其他线程在访问同一全局变量时可能会读取到这个修改后的值。
如果一个线程使用new在堆上分配了内存并在线程执行过程中释放了这块内存那么其他线程在访问这块内存时可能会遇到悬挂指针dangling pointer或无效内存访问的问题
因此在多线程编程中对于共享的资源包括全局变量和动态分配的内存如new操作必须非常小心。应该通过合适的同步机制例如互斥锁、条件变量等来确保多个线程对这些资源的安全访问。这样可以避免潜在的竞态条件和访问无效内存的问题。
在处理动态内存时最好的做法是由创建它的线程负责释放内存而不是在其他线程中释放。此外可以使用智能指针例如std::shared_ptr或std::unique_ptr来管理动态内存这样可以避免手动释放内存的问题。 二、线程的终止
1.WaitForSingleObject()函数 函数原型如下 DWORD WaitForSingleObject( HANDLE hHandle, // 要等待的内核对象的句柄这里是线程句柄 DWORD dwMilliseconds // 等待的时间以毫秒为单位INFINITE 表示无限等待 ); 第二个参数 dwMilliseconds 表示等待的时间以毫秒为单位。这个参数控制函数在等待对象状态变化时的行为
如果 dwMilliseconds 的值为 INFINITE-1则 WaitForSingleObject 会一直阻塞直到内核对象的状态发生变化。如果 dwMilliseconds 的值为 0则函数立即检查内核对象的状态然后返回不会等待。
其他正整数值表示等待的毫秒数。如果在指定的时间内对象的状态没有发生变化函数会返回一个值表示等待超时。
示例如下
#include iostream
#include windows.h
using namespace std;DWORD WINAPI myProThread(PVOID lp)
{//ExitThread(0); 强制终止线程Sleep(5000); //Windows 下 Sleep 以毫秒为单位这里是休眠 5 秒return 0;
}int main()
{DWORD id 0;HANDLE handle CreateThread(NULL, 0, myProThread, NULL, 0, id);DWORD result WaitForSingleObject(handle, 1); //这里是设定等待线程1毫秒为了测定超时if (result WAIT_OBJECT_0){// 线程结束可以继续处理cout 线程结束 endl;}else if (result WAIT_TIMEOUT){// 超时可以采取相应的措施cout 超时了 endl;}else if (result WAIT_FAILED){// 函数调用失败可以通过 GetLastError() 获取错误信息DWORD dwError GetLastError();cout 线程错误代码为 dwError endl;}cout 该线程的ID是 id endl;CloseHandle(handle); //关闭线程句柄return 0;
}// 等待线程结束 2.ExitThread()函数:
ExitThread 函数可以用于在线程函数内部直接退出线程。但是需要注意使用此函数会终止线程的执行不会调用线程的析构函数也不会释放线程所占用的资源。这可能会导致资源泄漏或程序的不稳定性。
只能在线程内使用终止该线程
示例如下
代码
#include iostream
#include windows.h
using namespace std;DWORD WINAPI myProThread(PVOID lp)
{ExitThread(0); //强制终止线程Sleep(5000); //Windows 下 Sleep 以毫秒为单位这里是休眠 5 秒return 0;
}int main()
{DWORD id 0;HANDLE handle CreateThread(NULL, 0, myProThread, NULL, 0, id);DWORD result WaitForSingleObject(handle, 1); //这里是设定等待线程1毫秒为了测定超时if (result WAIT_OBJECT_0){// 线程结束可以继续处理cout 线程结束 endl;}else if (result WAIT_TIMEOUT){// 超时可以采取相应的措施cout 超时了 endl;}else if (result WAIT_FAILED){// 函数调用失败可以通过 GetLastError() 获取错误信息DWORD dwError GetLastError();cout 线程错误代码为 dwError endl;}cout 该线程的ID是 id endl;CloseHandle(handle); //关闭线程句柄return 0;
}// 等待线程结束 运行结果 3.TerminateThread()函数:
TerminateThread 函数可以用来强制终止一个线程。然而这个函数不安全因为它会立即终止线程的执行而不管线程正在做什么。这可能会导致未释放的资源不稳定的状态以及可能影响整个进程的问题。推荐避免使用这个函数。
可以在线程外使用终止指定线程 这里不做示例只提供函数如何使用 TerminateThread(hThread, 0); //第一个参数是线程句柄第二个参数是退出码(无意义) 4.CloseHandle()函数:
如果你有线程的句柄可以使用 CloseHandle 函数来关闭线程句柄。这不会终止线程但会释放句柄所占用的资源。这个函数的主要作用是清理句柄而不是终止线程。
注在关闭线程句柄之前通常应该确保线程已经退出或者至少没有使用线程句柄引用了线程。 5.正常return 0;
不做赘述。 三、线程的恢复与挂起
1.挂起线程
PS下列代码输出求挂起数时加了1。
①SuspendedThread()函数:
参数为线程句柄返回值为先前的挂起数即调用该函数次数
示例如下
代码
#include iostream
#include windows.h
using namespace std;DWORD WINAPI myProThread(PVOID lp)
{//ExitThread(0); //强制终止线程Sleep(5000); //Windows 下 Sleep 以毫秒为单位这里是休眠 5 秒return 0;
}int main()
{DWORD id 0;HANDLE handle CreateThread(NULL, 0, myProThread, NULL, 0, id); //第五个参数表示创建完成时挂起线程cout 该线程的ID是 id endl;DWORD result WaitForSingleObject(handle, 3000); //这里是设定等待线程1毫秒为了测定超时// 挂起线程DWORD suspendCount SuspendThread(handle);cout 初始挂起数为 suspendCount 1 endl;// 检查是否成功挂起线程if (suspendCount ! -1) {cout 线程已挂起 endl;} else {cerr 无法挂起线程 endl;}if (result WAIT_OBJECT_0){// 线程结束可以继续处理cout 线程结束 endl;}else if (result WAIT_TIMEOUT){// 超时可以采取相应的措施cout 超时了 endl;}else if (result WAIT_FAILED){// 函数调用失败可以通过 GetLastError() 获取错误信息DWORD dwError GetLastError();cout 线程错误代码为 dwError endl;}CloseHandle(handle); //关闭线程句柄return 0;
} 结果 ②CreateThread()的第五个参数设为CEREATE_SUSPENDED
代码同上只是在创建线程时把第五个参数设为CEREATE_SUSPENDED了
结果 四、线程的优先级
在 Windows 下C 程序可以使用线程库Thread Library来创建和管理线程。在 Windows 中线程优先级用于确定操作系统在有多个线程要执行时如何进行线程调度。Windows 提供了一组函数和常量来设置和获取线程的优先级。以下是关于 Windows 下 C 线程优先级的重要信息
1. **线程优先级范围** 在 Windows 系统中线程的优先级范围通常是从 0最低优先级到 31最高优先级。
2. **默认优先级** 当创建一个新线程时它默认会继承创建它的线程的优先级。
3. **设置线程优先级** 可以使用 SetThreadPriority 函数来设置线程的优先级。该函数的原型如下 BOOL SetThreadPriority( HANDLE hThread, int nPriority ); - hThread要设置优先级的线程句柄。 - nPriority要设置的优先级可以是以下常量之一 - THREAD_PRIORITY_IDLE - THREAD_PRIORITY_LOWEST - THREAD_PRIORITY_BELOW_NORMAL - THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_ABOVE_NORMAL - THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_TIME_CRITICAL 4. **获取线程优先级** 可以使用 GetThreadPriority 函数来获取线程的当前优先级。该函数的原型如下 int GetThreadPriority( HANDLE hThread ); - hThread要查询优先级的线程句柄。 需要注意的是虽然可以通过设置线程的优先级来影响线程的调度但是过度使用优先级可能会导致问题如饥饿、不公平调度等。正确地使用同步机制和合适的线程优先级以确保程序的稳定性和可预测性是良好的多线程编程实践的一部分。
在实际开发中除非你有明确的需求一般不建议频繁地改变线程的优先级而是让操作系统自行管理线程调度以确保整个系统的平稳运行。