博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程编程中的线程同步问题
阅读量:6174 次
发布时间:2019-06-21

本文共 2145 字,大约阅读时间需要 7 分钟。

  首先来看一个例子,从这个例子我们开始讨论这个问题

void main(){    HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadCallBack,NULL,0,NULL);    for (int i=0;i<100000;i++)    {        g1++;        g2++;    }    cout<
<

  在主函数中有一个线程进行for循环累加计算,但是子线程中也在进行计算,这势必会让两个线程的计算会交叉进行,导致最终输出的结果并不是我们想要的。

  在这里我有两种方法解决这个问题:

  一、使用临界区的

  首先解释什么是临界区:在任意时刻只允许一个线程对共享资源进行访问的区域,也就是多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题。 如果一个

线程负责改变此变量的值,而其他线程负责同时读取变量内容,则不能保证读取到的数据是经过写线程修改后的。为了确保读线程读取到的是经过修改的变量,就必须在向变量写入

数据时禁止其他线程对其的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。

CRITICAL_SECTION   cs; //临界区的声明void main(){    InitializeCriticalSection(&cs);       //初始化临界区    HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadCallBack,NULL,0,NULL);    EnterCriticalSection(&cs);       //进入临界区    for (int i=0;i<100000;i++)    {        g1++;        g2++;    }    LeaveCriticalSection(&cs);         //执行完出来    WaitForSingleObject(hThread,INFINITE);     //等子线程执行完    cout<
<

  使用临界区的方法之前要声明和初始化临界区。每个线程进入临界区之前,声明一下EnterCriticalSection(&cs)进入临界区,在线程执行完毕之后,LeaveCriticalSection(&cs)退出临界区,接着让其他线程进入临界区。

  在最后所有线程执行完毕时,要销毁临界区。

  二、设置事件

HANDLE  hEvent;  //线程同步  事件void main(){    hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);    HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadCallBack,NULL,0,NULL);    for (int i=0;i<100000;i++)    {        g1++;        g2++;    }    SetEvent(hEvent);      //设置事件信号    WaitForSingleObject(hThread,INFINITE);     //等子线程执行完    cout<
<

  首先是创建事件,此时的事件还未受信。当主线程执行完毕时,设置事件受信,子线程中的WaitForSingleObject函数收到信号后,会向下执行。在线程执行完成后,要关闭事件句柄。

  另外有几个小问题:

  一、函数的调用约定

  函数的调用约定就是描述参数是怎么传递和由谁平衡堆栈的,当然还有返回值。

  常用的调用约定如下:

  _cdecl

  1、参数是从右向左传递的,也是放在堆栈中。

  2、堆栈平衡是由调用函数来执行的。

  _stdcall

  Win32 API函数绝大部分都是采用__stdcall调用约定的。WINAPI也是__stacall的一个别名。

  1、参数是从右往左传递的,也是放在堆栈中。

  2、函数的堆栈平衡操作是由被调用函数执行的。

  二、句柄是什么?

  句柄是一个标识符,是拿来标识对象或者项目的。

  一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。

  应用程序能够通过句柄访问相应的对象的信息,但是句柄不是指针,程序不能利用句柄来直接阅读文件中的信息。

  如果句柄不在I/O文件中,它是毫无用处的。

  句柄是Windows用来标志应用程序中建立的或是使用的唯一整数,Windows大量使用了句柄来标识对象。

 

转载于:https://www.cnblogs.com/suvllian/articles/5432671.html

你可能感兴趣的文章
那些年我们经历过的运维
查看>>
安装带有调试信息的C库
查看>>
迷宫的基本实现
查看>>
Ajax跨域请求问题
查看>>
topic4:Qt入门之常用qt控件认知之Button系列
查看>>
jstack:Java堆栈跟踪工具
查看>>
源码安装 python3
查看>>
获取当前fragment
查看>>
linux centeros 7.4 修改主机名
查看>>
关于程序员,你知道的有多少?
查看>>
Tomcat问题汇总
查看>>
由于未预料的错误,现在无法使用nautilus
查看>>
业界最有价值的Linux资料大全(200篇)
查看>>
Arraylist动态扩容详解
查看>>
%cd%及%~dp0批处理命令的详解
查看>>
MySQL数据库负载很高连接数很多怎么处理
查看>>
关于延迟加载(lazy)和强制加载(Hibernate.initialize(Object proxy) )
查看>>
Cent OS 环境下 samba服务器的搭建
查看>>
vCloud Director 1.5.1 Install Procedure
查看>>
hive 中的多列进行group by查询方法
查看>>