windows下多个线程公用一个线程函数时候对某些变量需不需要进行同步的问题

 1.   多个线程可以使用同一个全局函数,需不需要处理同步视具体情况而定。
2.   全局函数中的局部变量互相不会影响,因为它们位于线程各自的堆栈中。
3.   全局函数中如果涉及了全局变量,那么对该全局变量的访问应该进行同步处理,可使用临界区、事件、信号量以及互斥体来进行同步。


函数内声明的局部变量操作编译时都只实现为偏移量形式的寻址,程序的每个线程运行时系统都分配给一个独立的栈,函数通过偏移量在这个栈里定位局部变量。
函数指令(不是函数体!)放在代码段,局部变量都在栈里;

被调用的函数都在代码段,每个线程都有自己的栈,可以存放自己的局部变量。
在程序装入内存时,全局变量在进程地址空间中已经分配,并初始化。所以它是线程共享的,修改时应该加以同步。

下面用几段代码来进行测试验证:

1.对于函数内部局部变量是相互独立的
如:通过打印局部变量地址,因为是在同一个进程中属于同一地址段,局部变量在栈中,在函数中是以偏移量来寻找地址,所以如果公用一个变量则地址应该相同:
#include <iostream>
#include <process.h>      //这个头文件中有CreateThread(),ExitThread(),CloseHandle()函数
#include <Windows.h>
#include <stdio.h>

using namespace std;

HANDLE handle1;
HANDLE handle2;
DWORD dw1,dw2;

DWORD WINAPI MyThread(void *p)
{
 int i = 10;
 cout << &i << endl;
 Sleep(10000);
 
 return 0;
}

int main()
{
 int count = 0;
 int *ptr = &count;
 handle1 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw1);
 Sleep(3000);
 handle2 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw2);


 Sleep(3000);
 return 0;
}
第二种方法:当一个进程进入时候把局部变量修改,另一个进程在修改变量之后进入这个线程,使用进程号来标识进入函数的是哪个线程,然后打印这个变量。
#include <iostream>
#include <process.h>      //这个头文件中有CreateThread(),ExitThread(),CloseHandle()函数
#include <Windows.h>
#include <stdio.h>

using namespace std;

HANDLE handle1;
HANDLE handle2;
DWORD dw1,dw2;

DWORD WINAPI MyThread(void *p)
{
 int i = 10; 
 if (GetCurrentThreadId() == dw1)
  i = i+3;
 if (GetCurrentThreadId() == dw1)
 {
  cout <<"The First Thread Coming Now!"<< endl;
 }
 if (GetCurrentThreadId() == dw2)
 {
  cout <<"The Second Thread Coming Now!"<< endl;
 }

 Sleep(3000);

 if (GetCurrentThreadId() == dw1)
 {
  cout <<"The First Thread Get The value of i is :"<< i << endl;
 }
 if (GetCurrentThreadId() == dw2)
 {
  cout << "The Second Thread Get The value of i is :"<< i << endl;
 }

 cout << "can go here now" << endl;
 Sleep(10000);
 
 return 0;
}

int main()
{
 int count = 0;
 int *ptr = &count;

 handle1 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw1);
 Sleep(1000);
 handle2 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw2);

 Sleep(100000);
 return 0;
}
2.对于一个全局变量,是属于这个进程的,这两个线程是公用的,同样可以用两种方法来验证这两个线程公用这个全局变量
打印变量地址:
#include <iostream>
#include <process.h>      //这个头文件中有CreateThread(),ExitThread(),CloseHandle()函数
#include <Windows.h>
#include <stdio.h>

using namespace std;

HANDLE handle1;
HANDLE handle2;
DWORD dw1,dw2;
int i;

DWORD WINAPI MyThread(void *p)
{
 i = 10;
 cout << &i << endl;
 Sleep(10000);
 
 return 0;
}

int main()
{
 int count = 0;
 int *ptr = &count;
 handle1 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw1);
 Sleep(3000);
 handle2 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw2);


 Sleep(3000);
 return 0;
}
修改之后打印变量值:
#include <iostream>
#include <process.h>      //这个头文件中有CreateThread(),ExitThread(),CloseHandle()函数
#include <Windows.h>
#include <stdio.h>

using namespace std;

HANDLE handle1;
HANDLE handle2;
DWORD dw1,dw2;
int i;

DWORD WINAPI MyThread(void *p)
{
 i = 10; 
 if (GetCurrentThreadId() == dw1)
  i = i+3;
 if (GetCurrentThreadId() == dw1)
 {
  cout <<"The First Thread Coming Now!"<< endl;
 }
 if (GetCurrentThreadId() == dw2)
 {
  cout <<"The Second Thread Coming Now!"<< endl;
 }

 Sleep(3000);

 if (GetCurrentThreadId() == dw1)
 {
  cout <<"The First Thread Get The value of i is :"<< i << endl;
 }
 if (GetCurrentThreadId() == dw2)
 {
  cout << "The Second Thread Get The value of i is :"<< i << endl;
 }

 cout << "can go here now" << endl;
 Sleep(10000);
 
 return 0;
}

int main()
{
 int count = 0;
 int *ptr = &count;

 handle1 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw1);
 Sleep(1000);
 handle2 = CreateThread(NULL,0,MyThread,(LPVOID)(ptr),0,&dw2);

 Sleep(100000);
 return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值