CreateThread的参数问题

rongxiaojun 2014-04-23 04:59:42
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <process.h>
#include <string>
#include <vector>

typedef struct ThreadArg
{
int request_num;
unsigned long thread_no;
std::string request_msg;

ThreadArg()
{
request_num = 0;
thread_no = 0;
request_msg = "";
}
}ThreadArg;

DWORD WINAPI func(LPVOID arg)
{
ThreadArg *tharg = (ThreadArg*)arg;
std::cout<<tharg->thread_no<<std::endl;
return 0;
}

int main()
{
for(int i = 0; i < 10; i++)
{
ThreadArg tharg;
tharg.thread_no = i;
HANDLE worker = CreateThread(NULL, 0, func, &ThreadArg, 0, NULL);
}
}



输出的并不是 0-9 啊,问题:
1.有很多重复的数字。
2.有很多很大的数字。

求解答。
...全文
209 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
mujiok2003 2014-04-24
  • 打赏
  • 举报
回复
std::cout是个全局变量, 需要考虑同步。
赵4老师 2014-04-24
  • 打赏
  • 举报
回复
《Windows核心编程》
赵4老师 2014-04-24
  • 打赏
  • 举报
回复
线程顺序是靠锁来保证和维持的;而不是靠什么Sleep!
ztenv 版主 2014-04-24
  • 打赏
  • 举报
回复
加锁在多线程中是常用的,但会降低效率,以后项目开发时你慢慢就会明白。
rongxiaojun 2014-04-24
  • 打赏
  • 举报
回复
引用 8 楼 u010005508 的回复:
[quote=引用 楼主 rongxiaojun 的回复:]
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <process.h>
#include <string>
#include <vector>

typedef struct ThreadArg
{
	int request_num;
	unsigned long thread_no;
	std::string request_msg;

	ThreadArg()
	{
		request_num = 0;
		thread_no = 0;
		request_msg = "";
	}
}ThreadArg;

DWORD WINAPI func(LPVOID arg)
{
	ThreadArg *tharg = (ThreadArg*)arg;
	std::cout<<tharg->thread_no<<std::endl;
	return 0;
}

int main()
{
for(int i = 0; i < 10; i++)
{
      ThreadArg tharg;
      tharg.thread_no = i;
      HANDLE worker = CreateThread(NULL, 0, func, &ThreadArg, 0, NULL);
}
}
输出的并不是 0-9 啊,问题: 1.有很多重复的数字。 2.有很多很大的数字。 求解答。
原因:1.main函数都没有返回值,不知道你咋通过编译的 2.建了10个线程,每个线程传递的都是局部变量的,局部变量作用域仅限于for{}中,因此出了for之后,局部变量就拜拜了 3.给每个线程传递的参数是变量类型,而不是声明的变量!这这也用过编译了吗? 将main函数改为如下即可:

	int main()
{
	ThreadArg TArg[10];
	for(int i = 0; i < 10; i++)
	{
		TArg[i].thread_no = i;
		HANDLE worker = CreateThread(NULL, 0, func, (LPVOID)&TArg[i], 0, NULL);
	}
	Sleep(5000);
	return 0;
}
在主线程作用域中创建一个数组用于将数组每个元素分别传递给每个子线程,创建完子线程后,主线程等待一会让子线程进行输出; 由于线程调度是不可控的,因此这里输出的顺序是混乱的,而且每个子线程输出数字后,有可能还没来得及输出endl时,OS就开始调度其它子线程了,因此输出顺序和格式可能每次都不一样;如下图所示,就将1和8输出在同一行了: [/quote] 感谢你解决了我的问题,原来输出错误是因为线程调度的问题,我在子线程输出的地方加了把锁,输出果然正常了,感谢你和二楼的lianshaohua。
rongxiaojun 2014-04-24
  • 打赏
  • 举报
回复
引用 8 楼 u010005508 的回复:
[quote=引用 楼主 rongxiaojun 的回复:]
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <process.h>
#include <string>
#include <vector>

typedef struct ThreadArg
{
int request_num;
unsigned long thread_no;
std::string request_msg;

ThreadArg()
{
request_num = 0;
thread_no = 0;
request_msg = "";
}
}ThreadArg;

DWORD WINAPI func(LPVOID arg)
{
ThreadArg *tharg = (ThreadArg*)arg;
std::cout<<tharg->thread_no<<std::endl;
return 0;
}

int main()
{
for(int i = 0; i < 10; i++)
{
ThreadArg tharg;
tharg.thread_no = i;
HANDLE worker = CreateThread(NULL, 0, func, &ThreadArg, 0, NULL);
}
}



输出的并不是 0-9 啊,问题:
1.有很多重复的数字。
2.有很多很大的数字。

求解答。

原因:1.main函数都没有返回值,不知道你咋通过编译的
2.建了10个线程,每个线程传递的都是局部变量的,局部变量作用域仅限于for{}中,因此出了for之后,局部变量就拜拜了
3.给每个线程传递的参数是变量类型,而不是声明的变量!这这也用过编译了吗?
将main函数改为如下即可:

int main()
{
ThreadArg TArg[10];
for(int i = 0; i < 10; i++)
{
TArg[i].thread_no = i;
HANDLE worker = CreateThread(NULL, 0, func, (LPVOID)&TArg[i], 0, NULL);
}
Sleep(5000);
return 0;
}

在主线程作用域中创建一个数组用于将数组每个元素分别传递给每个子线程,创建完子线程后,主线程等待一会让子线程进行输出;
由于线程调度是不可控的,因此这里输出的顺序是混乱的,而且每个子线程输出数字后,有可能还没来得及输出endl时,OS就开始调度其它子线程了,因此输出顺序和格式可能每次都不一样;如下图所示,就将1和8输出在同一行了:
[/quote]

我输出100次,出现的结果是:


兜兜_ 2014-04-24
  • 打赏
  • 举报
回复
int iSignal = 0; // 要顺序输出就要控制他们数据来源,你不理解多线程。 DWORD WINAPI func(LPVOID arg) { ThreadArg *tharg = (ThreadArg*)arg; while ( true ) { if ( (tharg->thread_no==iSignal) ) { std::cout<<tharg->thread_no<<std::endl; break; } else { Sleep(1000); } } iSignal ++; return 0; } int main() { ThreadArg *thargs = new ThreadArg[100]; for(int i = 0; i < 100; i++) { thargs[i].thread_no = i; CreateThread(NULL, 0, func, &thargs[i], 0, NULL); } while ( true ) { if ( iSignal == 100 ) { break; } Sleep(1000); } delete[] thargs; return 0; }
xdayong 2014-04-24
  • 打赏
  • 举报
回复
//改成类似于单线程处理 for(int i = 0; i < 10; i++) { ThreadArg tharg; tharg.thread_no = i; HANDLE worker = CreateThread(NULL, 0, func, &ThreadArg, 0, NULL); WaitForSingleObject( worker , INFINITE); }
highnewrain 2014-04-23
  • 打赏
  • 举报
回复
引用 楼主 rongxiaojun 的回复:
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <process.h>
#include <string>
#include <vector>

typedef struct ThreadArg
{
int request_num;
unsigned long thread_no;
std::string request_msg;

ThreadArg()
{
request_num = 0;
thread_no = 0;
request_msg = "";
}
}ThreadArg;

DWORD WINAPI func(LPVOID arg)
{
ThreadArg *tharg = (ThreadArg*)arg;
std::cout<<tharg->thread_no<<std::endl;
return 0;
}

int main()
{
for(int i = 0; i < 10; i++)
{
ThreadArg tharg;
tharg.thread_no = i;
HANDLE worker = CreateThread(NULL, 0, func, &ThreadArg, 0, NULL);
}
}



输出的并不是 0-9 啊,问题:
1.有很多重复的数字。
2.有很多很大的数字。

求解答。

原因:1.main函数都没有返回值,不知道你咋通过编译的
2.建了10个线程,每个线程传递的都是局部变量的,局部变量作用域仅限于for{}中,因此出了for之后,局部变量就拜拜了
3.给每个线程传递的参数是变量类型,而不是声明的变量!这这也用过编译了吗?
将main函数改为如下即可:

int main()
{
ThreadArg TArg[10];
for(int i = 0; i < 10; i++)
{
TArg[i].thread_no = i;
HANDLE worker = CreateThread(NULL, 0, func, (LPVOID)&TArg[i], 0, NULL);
}
Sleep(5000);
return 0;
}

在主线程作用域中创建一个数组用于将数组每个元素分别传递给每个子线程,创建完子线程后,主线程等待一会让子线程进行输出;
由于线程调度是不可控的,因此这里输出的顺序是混乱的,而且每个子线程输出数字后,有可能还没来得及输出endl时,OS就开始调度其它子线程了,因此输出顺序和格式可能每次都不一样;如下图所示,就将1和8输出在同一行了:
u012997273 2014-04-23
  • 打赏
  • 举报
回复
引用 6 楼 lianshaohua 的回复:
结果乱还是顺序不对? 如果顺序不对就在for循环创建线程后sleep一下,
++
ztenv 版主 2014-04-23
  • 打赏
  • 举报
回复
结果乱还是顺序不对? 如果顺序不对就在for循环创建线程后sleep一下,
rongxiaojun 2014-04-23
  • 打赏
  • 举报
回复
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <process.h>
#include <string>
#include <vector>

typedef struct ThreadArg
{
	int request_num;
	unsigned long thread_no;
	std::string request_msg;

	ThreadArg()
	{
		request_num = 0;
		thread_no = 0;
		request_msg = "";
	}
}ThreadArg;

DWORD WINAPI func(LPVOID arg)
{
	ThreadArg *tharg = (ThreadArg*)arg;
	std::cout<<tharg->thread_no<<std::endl;
	return 0;
}

int main()
{
    ThreadArg *thargs = new ThreadArg[100];
    for(int i = 0; i < 100; i++)
    {
          thargs[i].thread_no = i;
          HANDLE worker = CreateThread(NULL, 0, func, &thargs[i], 0, NULL);
    } 
    Sleep(10000);
    delete[] thargs;
    return 0;
}
不能正确输出0-99!
rongxiaojun 2014-04-23
  • 打赏
  • 举报
回复
引用 1 楼 lianshaohua 的回复:
ThreadArg tharg; tharg.thread_no = i; 你把这个new出来再试试,你这样写没异常退出就不错了; 局部变量的指针不能使用的;
不好意思,问题并没有解决。 10次没问题,一旦改为i < 100 就又有问题了。
ztenv 版主 2014-04-23
  • 打赏
  • 举报
回复
引用 2 楼 rongxiaojun 的回复:
[quote=引用 1 楼 lianshaohua 的回复:] ThreadArg tharg; tharg.thread_no = i; 你把这个new出来再试试,你这样写没异常退出就不错了; 局部变量的指针不能使用的;
谢谢你,帮我解决了 1.“局部变量的指针不能使用的”,先new出来。 2.for完了后Sleep(5000),否则还会有麻烦。[/quote] sleep(5000) 仅针对你这个程序吧,否则要检测所有线程退出才能结束main的
rongxiaojun 2014-04-23
  • 打赏
  • 举报
回复
引用 1 楼 lianshaohua 的回复:
ThreadArg tharg; tharg.thread_no = i; 你把这个new出来再试试,你这样写没异常退出就不错了; 局部变量的指针不能使用的;
谢谢你,帮我解决了 1.“局部变量的指针不能使用的”,先new出来。 2.for完了后Sleep(5000),否则还会有麻烦。
ztenv 版主 2014-04-23
  • 打赏
  • 举报
回复
ThreadArg tharg; tharg.thread_no = i; 你把这个new出来再试试,你这样写没异常退出就不错了; 局部变量的指针不能使用的;

65,208

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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