下面代码运行显示结果如图;为什么会有相同的线程编号?
#include <stdio.h>
#include <process.h>
#include <windows.h>
long g_nNum;
unsigned int __stdcall Fun(void *pPM);
const int THREAD_NUM = 10;
//关键段变量声明
CRITICAL_SECTION g_csThreadParameter, g_csThreadCode;
int main()
{
HANDLE handle[10];
int i = 0;
//关键段初始化
InitializeCriticalSection(&g_csThreadParameter);
InitializeCriticalSection(&g_csThreadCode);
g_nNum = 0;
while (i < THREAD_NUM)
{
EnterCriticalSection(&g_csThreadParameter);//进入子线程序号关键区域
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
LeaveCriticalSection(&g_csThreadParameter);//离开子线程序号关键区域
++i;
}
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
DeleteCriticalSection(&g_csThreadCode);
DeleteCriticalSection(&g_csThreadParameter);
return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
int nThreadNum = *(int *)pPM;
Sleep(50);//some work should to do
EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域
g_nNum++;
Sleep(0);//some work should to do
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
LeaveCriticalSection(&g_csThreadCode);//离开各子线程互斥区域
return 0;
}
#include <stdio.h>
#include <process.h>
#include <windows.h>
long g_nNum;
unsigned int __stdcall Fun(void *pPM);
const int THREAD_NUM = 10;
//关键段变量声明
CRITICAL_SECTION g_csThreadParameter, g_csThreadCode;
int main()
{
HANDLE handle[10];
int i = 0;
//关键段初始化
InitializeCriticalSection(&g_csThreadParameter);
InitializeCriticalSection(&g_csThreadCode);
g_nNum = 0;
while (i < THREAD_NUM)
{
EnterCriticalSection(&g_csThreadParameter);//进入子线程序号关键区域
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
LeaveCriticalSection(&g_csThreadParameter);//离开子线程序号关键区域
++i;
}
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
DeleteCriticalSection(&g_csThreadCode);
DeleteCriticalSection(&g_csThreadParameter);
return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
int nThreadNum = *(int *)pPM;
Sleep(50);//some work should to do
EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域
g_nNum++;
Sleep(0);//some work should to do
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
LeaveCriticalSection(&g_csThreadCode);//离开各子线程互斥区域
return 0;
}
解决方案 »
- 0x000006D9: 终结点映射器中没有更多的终结点可用 是咋回事?
- 模拟键盘退格??
- CSocket在线程中的Receive时出现系统异常,弹出error后,整个应用程序终了,线程中Send没问题,为什么啊???
- CComboBox控件在MoveWindow后下拉框就出不来了
- 保护类型函数如何在其他类里调用
- vod 网络编程求助?
- 请问在2000下面如何设置系统时间?
- 如何设置VB ocx与Asp页面的接口?讨教 let好像不可以
- 操纵execl关闭自动重算的问题
- 如何在DLL中, 正确传递一个参数到线程?
- _tcscpy_s,_tcstok_s 等等函数VC 6.0下如何调用
- 求助:引入列表控功能件增强类后,表头不能修改文字内容
/MLd对应调试版单线程静态标准库(libcd.lib),VC6默认是以单线程库运行的,如果你创建的是win32 console application
{
EnterCriticalSection(&g_csThreadParameter);//进入子线程序号关键区域
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
LeaveCriticalSection(&g_csThreadParameter);//离开子线程序号关键区域
++i;
} 比如创建了1线程,这个时候i为0,退出临界区,然后又继续创建了2线程,这个时候i是1.。。但是1线程可能刚刚执行,但是i已经变了,因为你传到线程中的参数是i的指针地址。
我是这样设置;
//int nThreadNum = *(int *)pPM;
Sleep(50);//some work should to do
EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域
g_nThreadNum++;
g_nNum++;
Sleep(0);//some work should to do
printf("线程编号为%d 全局资源值为%d\n", g_nThreadNum, g_nNum);
LeaveCriticalSection(&g_csThreadCode);//离开各子线程互斥区域
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, (LPVOID)i, 0, NULL);
线程函数中也要修改一下:
int nThreadNum = (int)pPM;
他已经说清楚了,你传递的是i的地址,而不是i本身的值,就好比你传递的是指针,并不是指针的值,这个指针的值可能后来会被修改,所以你通过*p得到指针的值就可能是修改后的值。
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, (LPVOID)i, 0, NULL);
线程函数中也要修改一下:
int nThreadNum = (int)pPM; 正解,可以了。