Windows线程
admin
2024-01-21 03:29:39
0

Windows线程

线程基础
  • Windows线程是可以执行的代码的实例。

    系统是以线程为单位调度程序,一个程序中可以有多个线程,实现多任务的处理。主线程只能有一个。

  • Windows线程的特点

    1. 线程都具有1个ID
    2. 每个线程都具有自己的内存栈,其余的共享。
    3. 同一进程中的线程使用同一个地址空间。(除了栈空间)
  • 线程的调度

    操作系统将CPU的执行时间划分为时间片,依次根据时间片执行不同的线程。

    线程轮询: 线程A -> 线程B ->线程A …

创建线程
  • 创建线程

    HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes , // 安全属性,已废弃, NULLSIZE_T dwStackSize, // 线程栈的大小  按1M对齐,最少1MLPTHREAD_START_ROUTINE lpStartAddress, // 线程处理函数的函数地址,自己定义由系统调用LPVOID lpParameter, // 传递给线程处理函数的参数DWORD dwCreationFlags, // 线程的创建方式(立即执行&挂起方式)// 0 -> 立即启动// CREATE_SUSPENDED -> 挂起LPDWORD lpThreadId // 创建成功,返回线程的ID
    ); // 创建成功,返回线程句柄  ( 线程句柄和线程ID都可以代表线程 )
    
  • 定义线程处理函数

    DWORD WINAPI ThreadProc(LPVOID lpParameter // 创建线程时,传递给线程的参数
    );
    

Demo

#include 
#include 
DWORD CALLBACK TestProc(LPVOID pParam){char * pszText = (char *) pParam;printf("%s",pszText);
}
int main(){DWORD nID = 0;char * pszText = "******";HANDLE hThread = CreateThread(NULL,0,TestProc,pszText,0,&nID);getchar();return 0;
}

子线程正常执行->要保证主线程不结束

销毁线程
  • 挂起

    DWORD SuspendThread(HANDLE hThread // 线程句柄
    );
    
  • 唤醒

    DWORD ResumeThread(HANDLE hThread  // 线程句柄
    );
    
  • 结束指定线程

    BOOL TerminateThread(HANDLE hThread, // 线程句柄DWORD dwExitCode // 退出码,一般没用
    );
    
  • 结束函数所在的线程

    VOID ExitThread(DWORD dwExitCode // 退出码,没有实际意义
    );
    // 自杀 -> 只能干掉调用的线程
    
线程相关操作
  • 获取当前线程ID

    GetCurrentThreadId();
    
  • 获取当前线程的句柄

    GetCurrentThread();
    
  • 等候单个句柄有信号

    VOID WaitForSingleObject(HANDLE handle , // 句柄BUFF的地址DWORD dwMilliseconds // 最长等候时间 ms// INFINITE 一直等待
    );
    // 有信号时会立即返回
    // 没有信号会阻塞
    

    线程句柄是可等候句柄: 有信号和无信号状态

  • 同时等候多个句柄有信号

    DWORD WaitForMultipleObject(DWORD nCount, // 句柄数量CONST HANDLE *lpHandles, // 句柄BUFF的地址BOOL bWaitAll, // 等候方式// TRUE : 所有句柄都有信号才会返回// FALSE: 只要有一个有信号就返回DWORD dwMilliseconds // 等候时间  INFINITE
    );
    

    可等候句柄

  • 线程信号

    • 当线程处于执行状态时,线程无信号
    • 当线程结束那刻,线程有信号
线程同步
原子锁
  • 当多个线程对同一个数据进行原子操作,会产生结果丢失,比如算术运算

  • 使用原子锁函数

    InterlockedIncrement   // ++ 操作符
    InterlockedDecrement   // --
    InterlockedCompareExchange   // 三目运算符 
    InterlockedExchange    // = 赋值
    

    原子锁的实现,直接对数据所在的内存操作,并且任何一个瞬间只能有一个线程访问。

  • 只能对运算符加锁,效率高,但是麻烦

互斥锁
  • 相关问题

    多线程下代码或者资源的共享使用

  • 互斥的使用

    1. 创建互斥

      HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全数据(NULL)BOOL bInitialOwner, // 初始的拥有者 TRUE/FALSE// TRUE: 哪个线程创建哪个线程拥有// FALSE: 都不拥有LPCTSTR lpName // 命名
      ); // 创建成功返回互斥句柄
      // 互斥句柄,也是可等候句柄
      
      • 在任何时间点上只有一个线程拥有互斥, 独占性和排他性

      • 当任何线程都不拥有互斥,互斥有信号,任何一个线程拥有互斥,互斥就没有信号

    2. 等候互斥

      WaitFor… 函数

      互斥的等候遵循谁先等候谁先获得

      也就是加锁

    3. 释放互斥

      BOOL ReleaseMutex(HANDLE hMutex // 互斥锁句柄
      );
      
    4. 关闭互斥句柄

      CloseHandle
      

demo

#include 
#include HANDLE hmutex; // 接收互斥句柄 DWORD CALLBACK TestProc(LPVOID pParam){char * pszText = (char *) pParam;int i ;while(1){WaitForSingleObject(hmutex,INFINITE);for(i = 0;iprintf("%c",pszText[i]);Sleep(125);}printf("\n");ReleaseMutex(hmutex); } 
}
int main(){hmutex = CreateMutex(NULL,FALSE,NULL); DWORD nID1 = 0;DWORD nID2 = 0;char * pszText1 = "******";char * pszText2 = "------";HANDLE hThread1 = CreateThread(NULL,0,TestProc,pszText1,0,&nID1);HANDLE hThread2 = CreateThread(NULL,0,TestProc,pszText2,0,&nID2);getchar();CloseHandle(hmutex);return 0;
}
事件
  • 相关问题

    线程之间的通知问题

  • 事件的使用

    1. 创建事件

      HANDLE CreateEvent(LPSEURITY_ATTRIBUTES lpEventAttributes, // 安全属性BOOL bManualReset, // 事件重置(复位)方式 有信号 -> 无信号// TRUE  手动// FALSE 自动 --> 读取信号一次就会自动复位// 触发 无信号 ->有信号BOOL bInitialState ,// 事件初始状态,TRUE 有信号LPCTSTR lpName // 事件命名,可以为空
      );// 创建成功返回事件句柄
      

      可等候句柄

      事件的有信号无信号可控制

    2. 等候事件

      WaitForSingleObject  / WaitForMultipleObjects
      // 自动复位方式,会自动复位
      
    3. 触发事件( 将事件设置为有信号状态)

      BOOL SetEvent(HANDLE hEvent //handle to event
      );
      
    4. 复位事件( 将事件设置为无信号状态 )

      BOOL ResetEvent(HANDLE hEvent
      );
      
    5. 关闭事件

      CloseHandle
      

要小心事件的死锁问题

demo

#include 
#include 
HANDLE g_hEvent = 0; // 接收事件句柄DWORD CALLBACK PrintProc(LPVOID pParam){while(1){WaitForSingleObject(g_hEvent,INFINITE); // 等待信号 ResetEvent(g_hEvent); printf("......\n");}
}DWORD CALLBACK CtrlProc(LPVOID pParam){while(1){Sleep(1000);SetEvent(g_hEvent);}
} 
int main(){g_hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);DWORD nID = 0;HANDLE hThread[2] = {0};hThread[0] = CreateThread(NULL,0,PrintProc,NULL,0,&nID); hThread[1] = CreateThread(NULL,0,CtrlProc,NULL,0,&nID);WaitForMultipleObjects(2,hThread,TRUE,INFINITE);CloseHandle(g_hEvent);return 0; 
}
信号量
  • 相关的问题

    作用类似于事件,解决通知的相关问题。

    提供一个计数器,可以设置次数

  • 信号量的使用

    1. 创建信号量

      HANDLE CreateSemaphore(LPSECTRITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性LONG lInitialCount, // 初始化信号量数量// 信号量计数值为0时,没有信号// 信号量计数值不为0,有信号LONG lMaximumCount, // 信号量最大个数LPCTSTR lpName // 命名
      );// 创建成功返回信号量句柄
      

      可等候句柄

    2. 等候信号量

      WaitFor ...
      // 每等候通过一次,信号量的信号减1,直到为0阻塞
      
    3. 给信号量指定计数值

      BOOL ReleaseSemaphore(HANDLE hSemaphore, // 信号量句柄LONG lReleaseCount ,// 释放数量LPLONG lpPreviousCount // 返回的信息,返回释放前原来信号量的数量,可以为NULL
      );
      
    4. 关闭句柄

      CloseHandle
      

demo

#include 
#include 
HANDLE g_hSema = 0;// 保存信号量句柄DWORD CALLBACK TestProc(LPVOID pParam){while(1){WaitForSingleObject(g_hSema,INFINITE);printf("*****\n");}
}int main(){g_hSema = CreateSemaphore(NULL,3,10,NULL);DWORD nID = 0;HANDLE hThread = CreateThread(NULL,0,TestProc,NULL,0,&nID);getchar();ReleaseSemaphore(g_hSema,5,NULL);WaitForSingleObject(hThread,INFINITE);CloseHandle(g_hSema);	return 0;
}

相关内容

热门资讯

阿里千问App全球首发点外卖、... 1月15日,阿里举行千问App发布会, 阿里巴巴(BABA.US)集团副总裁吴嘉宣布,千问App全面...
携程港股、美股放量跌近20% 【大河财立方消息】1月15日,携程港股、美股双双大跌。 截至发稿,港股携程集团跌幅18.53%,美股...
淳厚基金获国资入主!管理规模缩... 淳厚基金获得长宁国投入主,但是市场声誉遭遇重挫,机构投资者纷纷撤出。 文/每日财报 楚风 随着国有...
「死了么」爆火,1亿独居群体被... 「核心提示」 独居时代下的深层焦虑,让“死了么”迎来短暂流量狂欢。不过,这款低门槛应用,拿什么...
2025年我国跨境电商进出口2... 一、明星品牌 1、美国奢侈品零售商萨克斯环球申请破产保护 美国高端百货集团萨克斯环球(Saks Gl...
卫龙前CEO孙亦农入职大窑出任... 红星资本局1月15日消息,红星资本局从大窑处了解到,卫龙(09985.HK)前CEO孙亦农已加入大窑...
市场利好持续提振港股医药股 东... 财联社1月15日讯(编辑 胡家荣)今日港股医药板块迎来强劲反弹,多只个股表现亮眼。截至发稿,东曜药业...
技术派登顶!2026浙江危机公... 2026年危机公关行业正经历近十年来最深刻的范式革命。当抖音热搜的存活周期缩短至3小时、AI生成虚假...
雷军官宣今晚直播:与汽车媒体一... 2026年1月15日,小米创办人,董事长兼CEO雷军在社交媒体平台发文称,“上次直播后,很多网友希望...
阿里千问宣布接入淘宝、支付宝、... 1月15日,阿里千问App宣布全面接入淘宝、支付宝、淘宝闪购、飞猪、高德等阿里生态业务,在全球首先实...
黄金投资交易入门:定义与风险评... 黄金投资交易是以黄金为交易标的的金融投资行为,核心是通过把握黄金价格的波动规律,以低买高卖的方式赚取...
第六批高值医用耗材集采开标,涉... 图片来源:视觉中国 蓝鲸新闻1月14日讯(记者 屠俊)据国家医保局官微信息显示,1月13日,第六批国...
瑞银:中国AI不堆卡、重效率,... “中国AI行业不存在美国式泡沫,反而将在模型出海、应用爆发、算力替代三大主线迎来系统性机遇。”1月1...
小鹏汇天冲击港股IPO:低空经... 2026年刚刚开始,小鹏汇天秘密提交港股IPO申请的消息就不胫而走。 有知情人士透露,小鹏汽车已聘请...
原创 马... 这将是一段动荡的旅程。 一 几周前,美国德州特斯拉超级工厂内,马斯克接受一次特殊访谈,预言2026。...
梁文锋旗下幻方量化,去年收益率... 每经记者|杨建 每经编辑|何小桃 叶峰 2025年A股市场持续火热,百亿私募交出了怎样的成绩单?据...
宽基ETF规模大增的三大理由 2026年,A股市场开局向好。Wind资讯数据显示,截至1月14日,开年以来ETF总规模增长超220...
冬季护眼 “睛”彩相伴|武汉普... 冬季天气寒冷干燥,室内取暖设备的使用让空气湿度降低,加上户外活动减少、长时间近距离用眼成为常态,干眼...
白银首破92美元,金铜锡拉升创... 2026年开年以来,全球金属市场迎来新一轮狂欢。 1月14日亚太交易时段,现货白银(伦敦银现)史上首...