您的位置:首页 > 其它

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

2011-10-09 21:52 453 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐