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;
}
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;
}
相关文章推荐
- JQuery ajax 如何设置同步调用(同时只能触发一个函数) 解决与层显示信息时候的冲突问题
- 线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局变量可以被两个线程同时使用,不过要注意的是线程间需要做好同步。
- 关于java多线程中同步的问题(两个线程访问同一个实例类的两个同步方法,会不会互相影响)
- js函数参数传值的时候遇到的一个小问题
- Java线程问题:当一个目标对象被多个线程共享时候
- 两个线程同时调用同一个处理函数的互斥问题
- javascript 中,哪些函数是对变量自身进行修改,哪些是创建一个新变量
- 函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包
- 1. 给定两个整形变量的值,将两个值的内容进行交换。 2. 不允许创建临时变量,交换两个数的内容(附加题) 3. 求10 个整数中最大值。 4. 写一个函数返回参数二进制中 1 的个数
- onethink如何在新增时一条数据的时候运行一个函数或进行某数据库的操作
- java线程同步问题(一个理解wait()与notify()的例子)
- Windows下修改环境变量后需不需要重启电脑的问题
- 黑马程序员------多线程(No.1)(概述、线程的创建、安全问题、同步锁、同步函数)
- java 多线程:开两个线程,一个线程跑同步代码块,一个线程跑同步函数
- python--多线程编程中的线程间通信的问题--变量同步锁
- 【我的问题】android:service里的一个内部线程类可以公用service的数据吗
- 基础篇_线程 第5集 多线程的安全问题--解决之道同步函数
- eclipse无法对某些函数进行代码提示的问题的解决
- 两个线程同时调用同一个处理函数的互斥问题
- C51内核单片机中用printf()函数进行打印时候,中断的问题