suspendthread 多个线程, 为什么 resumeThread后 只是开启了最后一个线程?

铭毅天下
大数据领域优质创作者
博客专家认证
2012-06-11 03:27:11
同题目,求解释?谢谢!
...全文
232 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiuchang 2012-06-12
  • 打赏
  • 举报
回复
问题的原因应该是就是互斥的问题,你把i不传指针,直接强制类型转换进线程应该就没有问题了
铭毅天下 2012-06-12
  • 打赏
  • 举报
回复
谢谢,有问题再和您交流。
我近期会一直做相关的研究。
尘雨 2012-06-12
  • 打赏
  • 举报
回复
for( int i = 0; i < 5; i++)
{
hThread[i] = CreateThread(NULL,0,ThreadProc,(LPVOID)&i,CREATE_SUSPENDED,NULL);
}

这有问题,你传递了i的指针地址进去。当某个线程内去访问这个指针指向的int数值时,它可能是个不确定的值,已经被循环++改变了实际内容

例如,第一个线程取到 i=1时的地址。但是当线程读这个地址时。这个地址指向的整数进入了下一个循环被自加了,变成了2.那么第一个线程,第二个线程可能取到的都是2.因为线程执行的顺序不一定和创建顺序一致.

所有的线程其实访问的都是同一个整型数据的指针地址。这个指针地址存放的数据又被主线程的循环修改,最终结果是5.由于主线程循环快(这个快不一定,只是你的测试环境,主线程循环快),子线程中也存在wait的操作,当wait完成,所取得的指针地址中的数据早已被主线程循环修改了。

所以你应该这样做
int nParam[5];
for( int i = 0; i < 5; i++)
{
nParam[i] = i;
hThread[i] = CreateThread(NULL,0,ThreadProc,(LPVOID)&(nParam[i]),CREATE_SUSPENDED,NULL);
}
铭毅天下 2012-06-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
检查一下你暂停和恢复时的线程句柄是否正确
[/Quote]


#include "stdafx.h"
#include "stdio.h"
#include <windows.h>

HANDLE hMutex = CreateMutex(NULL,false,NULL);

DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
WaitForSingleObject(hMutex,INFINITE);
int *p = (int*)(lpParameter);
printf("%d\n",*p);
ReleaseMutex(hMutex);
return 0;
}

int main(int argc, char* argv[])
{
HANDLE hThread[5];

for( int i = 0; i < 5; i++)
{
hThread[i] = CreateThread(NULL,0,ThreadProc,(LPVOID)&i,CREATE_SUSPENDED,NULL);
}

for( int j = 0; j < 5; j++ )
{
ResumeThread(hThread[j]);
WaitForSingleObject(hThread[j],INFINITE);
}

for( int k = 0; k < 5; k++ )
{
CloseHandle(hThread[k]);
}

return 0;
}


求解释,共同交流?谢谢!!
并且可不可以写个函数可以通过句柄hThread[i],让第i个线程执行?我想到的是
类似void exeThread(HANLE hThread); //hThread用于接收传入的线程句柄,好像
不行啊?
铭毅天下 2012-06-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
代码?
说实话,题目的操作过程没看明白。
[/Quote]


#include "stdafx.h"
#include "stdio.h"
#include <windows.h>

HANDLE hMutex = CreateMutex(NULL,false,NULL);

DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
WaitForSingleObject(hMutex,INFINITE);
int *p = (int*)(lpParameter);
printf("%d\n",*p);
ReleaseMutex(hMutex);
return 0;
}

int main(int argc, char* argv[])
{
HANDLE hThread[5];

for( int i = 0; i < 5; i++)
{
hThread[i] = CreateThread(NULL,0,ThreadProc,(LPVOID)&i,CREATE_SUSPENDED,NULL);
}

for( int j = 0; j < 5; j++ )
{
ResumeThread(hThread[j]);
WaitForSingleObject(hThread[j],INFINITE);
}

for( int k = 0; k < 5; k++ )
{
CloseHandle(hThread[k]);
}

return 0;
}

我希望输出的结果是:
1
2
3
4
5
但是实际结果是:
5
5
5
5
5
求解释,共同交流?谢谢!!
铭毅天下 2012-06-12
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
问题的原因应该是就是互斥的问题,你把i不传指针,直接强制类型转换进线程应该就没有问题了
[/Quote]
嗯,说的对。主要是10楼的原因,“你传递了i的指针地址进去。当某个线程内去访问这个指针指向的int数值时,它可能是个不确定的值,已经被循环++改变了实际内容”。
地址传递,值变都跟着变了。
谢谢您!
铭毅天下 2012-06-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

贴ThreadProc代码
[/Quote]

#include "stdafx.h"
#include "stdio.h"
#include <windows.h>

HANDLE hMutex = CreateMutex(NULL,false,NULL);

DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
WaitForSingleObject(hMutex,INFINITE);
int *p = (int*)(lpParameter);
printf("%d\n",*p);
ReleaseMutex(hMutex);
return 0;
}

int main(int argc, char* argv[])
{
HANDLE hThread[5];

for( int i = 0; i < 5; i++)
{
hThread[i] = CreateThread(NULL,0,ThreadProc,

(LPVOID)&i,CREATE_SUSPENDED,NULL);
}

for( int j = 0; j < 5; j++ )
{
ResumeThread(hThread[j]);
WaitForSingleObject(hThread[j],INFINITE);
}

for( int k = 0; k < 5; k++ )
{
CloseHandle(hThread[k]);
}

return 0;
}


我希望输出的结果是:

1

2

3

4

5

但是实际结果是:
5

5

5

5

5

求解释,共同交流?谢谢!!
尘雨 2012-06-11
  • 打赏
  • 举报
回复
for( int j = 0; j < 5; j++ )
{
ResumeThread(hThread[i]);
}

明显的bug
j是循环计数器,你循环内,使用的是i变量,当然是牛头对不上了。
stjay 2012-06-11
  • 打赏
  • 举报
回复
贴ThreadProc代码
铭毅天下 2012-06-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
检查一下你暂停和恢复时的线程句柄是否正确
[/Quote]

句柄是正确的,谢谢你!

楼上是问题的具体内容,再帮看下,很急,谢谢!
铭毅天下 2012-06-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
代码?
说实话,题目的操作过程没看明白。
[/Quote]


for( int i = 0; i < 5; i++)
{
HANDLE hThread[i] = CreateThread(NULL,0,ThreadProc,NULL,CREATE_SUSPENDED,NULL);
}

for( int j = 0; j < 5; j++ )
{
ResumeThread(hThread[i]);
}



大致是这样子,他们会访问同意线程,线程里使用互斥变量同步。
代码我做了精简,实际要传递一个和变量i有关的参数,即分别传递(1,2,3,4,5)。
为什么当ResumeThread()运行的时候,只运行最后一次传递的参数呢?
求解释?谢谢!
jiuchang 2012-06-11
  • 打赏
  • 举报
回复
检查一下你暂停和恢复时的线程句柄是否正确
ouyh12345 2012-06-11
  • 打赏
  • 举报
回复
代码?
说实话,题目的操作过程没看明白。

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧