我的c++多线程为什么运行比原来定义的线程还要多

#include"stdafx.h"#include<stdio.h>#include<winsock.h>#pragmacomment(lib,"wsock32.lib... #include "stdafx.h"
#include <stdio.h>
#include <winsock.h>
#pragma comment(lib,"wsock32.lib")
HANDLE g_hEvent;
typedef struct _ICMP_HEADER //ICMP 头部数据
{
BYTE bType; //8位类型
USHORT nCheckSum; //16位校验和
}ICMP_HEADER, *PICMP_HEADER;//首先是ICMP头部数据填写
typedef struct TagScanInfo
{
}ScanInfo,*PScanInfo;
USHORT GetCheckSum(LPBYTE lpBuff, DWORD dwSize)
{
DWORD dwCheckSum = 0;
USHORT* lpWord = (USHORT*)lpBuff;
while(dwSize > 1)
{
dwCheckSum += *lpWord++;
dwSize -= 2;
}
if(dwSize ==1)
dwCheckSum += *((LPBYTE)lpBuff);
return (USHORT)(~dwCheckSum);
}
unsigned long iSIP = inet_addr("192.168.1.103"); //开始IP
unsigned long iEIP = inet_addr("192.168.1.104"); //结束IP
unsigned long s1 = ntohl(iSIP);
unsigned long e1 = ntohl(iEIP);

int err,v=3389,i;
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
int idx = *(int*)lpParameter;
PScanInfo pinfo=(PScanInfo)lpParameter;
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family =AF_INET;
for(;s1 <= e1; s1++) //循环扫描IP
{
if(s1>=e1)//判断开始IP大或等于结束IP就结束循环
{
return 0;
}
WaitForSingleObject(g_hEvent,INFINITE);
addr.sin_port = htons(v);
addr.sin_addr.s_addr = htonl(s1);
err = connect(s,(struct sockaddr *)&addr, sizeof(addr));
if (err == INVALID_SOCKET)
printf("线程:%d %s %d Close \n",idx,inet_ntoa(addr.sin_addr), v);
else
printf("线程:%d %s %d Open \n",idx,inet_ntoa(addr.sin_addr), v);
Sleep(10);
SetEvent(g_hEvent);
}
return 0;
}
int main(int argc, char *argv[])
{

WSADATA wsaData;
WORD wVersionRequested;
wVersionRequested = MAKEWORD( 1, 1 );
WSAStartup( wVersionRequested, &wsaData );
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
int u = 3;
HANDLE* hThread = new HANDLE[u];
g_hEvent=CreateEvent(NULL, FALSE, FALSE,LPCTSTR("tickets"));
for(;i<u; i++)//循环创建子线程
{
if(s1>=e1)//判断开始IP大或等于结束IP就结束循环
{
return 0;
}

hThread[i]=CreateThread(NULL,0,Fun1Proc,&i,0,NULL);
Sleep(50);
}
SetEvent(g_hEvent);
WaitForMultipleObjects(u, hThread, TRUE, INFINITE);
for (i=0; i<u; i++)
CloseHandle(hThread[i]);
return 0;
}

开始IP为192.168.1.103 结束为192.168.1.104 线程数为3
扫描结果为
线程:0 192.168.1.103 3389 Open
线程:1 192.168.1.104 3389 Close
线程:2 192.168.1.105 3389 Close

不是应该为:
线程:0 192.168.1.103 3389 Open
线程:1 192.168.1.104 3389 Close
这样的吗 我就定义2个IP段 是不是线程数位3的原因? 要怎么结束多余的线程数?
虽然把线程数该为2 就可以解决 但是还想看看 怎么结束多余的线程
展开
 我来答
a52527459
2012-08-23 · TA获得超过510个赞
知道小有建树答主
回答量:597
采纳率:0%
帮助的人:332万
展开全部
你的 i 怎么 没有初始化啊??
i=0; 否则 可能是随机的,负数,那么如果没有条件if(s1>=e1) 将会创建 更多的线程。
你的全区参数e1 是线程不安全的。你最好用个 mutex 保证 其 安全。
你多线程,一个线程 到了 if(s1>=e1){}后面了,另一个线程却 修改了 s1 ,导致 它 超越了 e1 了。所以 你才会 获得 105 这个 ip。

总之 你应该看看 mutex,注意下 线程安全。
另外,你的线程 中 for(;s1 <= e1; s1++) //循环扫描IP 没有必要,应该放到 主函数中去。因为你想一个 线程 扫描 一个IP吧。要不 干嘛 弄两个 线程,都在循环 扫描 IP ?逻辑问题。
追问
哇 好厉害分析得好彻底 大神我是菜鸟要怎么修改重要的地方?
其实我就想一个线程扫描一个IP
当出现多于线程的时候 就关闭多于的线程
以为线程1和线程2 都有用 线程3没用到扫描ip 所以想关闭它 但是要怎么做?
追答
其实你的问题 很简单,全区变量 不要在 线程 中修改,否则 所有线程 都修改,就乱了。
传递的参数 修改 成 对应IP ,就行了。
贴上 修改后的程序:

//上面的代码 省略 不变
typedef struct{
int thread_no;
unsigned long ip_int32;
}threadParam_t;
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
int idx = (*(threadParam_t*)lpParameter).thread_no;
PScanInfo pinfo=(PScanInfo)lpParameter;
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family =AF_INET;
WaitForSingleObject(g_hEvent,INFINITE);
addr.sin_port = htons(v);
addr.sin_addr.s_addr = (*(threadParam_t*)lpParameter).ip_int32;/////////htonl(s1);//ip 就让 传参 来决定
err = connect(s,(struct sockaddr *)&addr, sizeof(addr));
if (err == INVALID_SOCKET)
printf("线程:%d %s %d Close \n",idx,inet_ntoa(addr.sin_addr), v);
else
printf("线程:%d %s %d Open \n",idx,inet_ntoa(addr.sin_addr), v);
Sleep(10);
SetEvent(g_hEvent);
return 0;
}
int main(int argc, char *argv[])
{
WSADATA wsaData;

WORD wVersionRequested;
wVersionRequested = MAKEWORD( 1, 1 );
WSAStartup( wVersionRequested, &wsaData );
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
int u = 2;
HANDLE* hThread = new HANDLE[u];
g_hEvent=CreateEvent(NULL, FALSE, FALSE,LPCTSTR("tickets"));
threadParam_t param;
for(i=0;i=e1)//判断开始IP大或等于结束IP就结束循环
{
return 0;
}
param.thread_no=i+1;
param.ip_int32=s1;
s1++;
hThread[i]=CreateThread(NULL,0,Fun1Proc,¶m,0,NULL);
Sleep(50);
//}
}
SetEvent(g_hEvent);
WaitForMultipleObjects(u, hThread, TRUE, INFINITE);
for (i=0; i<u; i++)
CloseHandle(hThread[i]);
return 0;
}
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式