C 如何";绕道;pthreads限制线程数
我这里有个小问题。我知道Linux限制了用户实际可以运行的线程数量 我正在使用C 如何";绕道;pthreads限制线程数,c,linux,pthreads,C,Linux,Pthreads,我这里有个小问题。我知道Linux限制了用户实际可以运行的线程数量 我正在使用pthread\u create和一个pthread\u t数组,限制为50(pthread\u t tid[50];)。我有一个for循环,每次限制达到50时,pthread\u t数组中的每个线程都会被终止 怎么做?我几乎测试了所有的东西。使用pthread_kill(tid[w],SIGKILL)w是一个简单的循环控制变量,从0变为50。我已经测试了pthread_cancel(tid[w])和问题继续存在 那么
pthread\u create
和一个pthread\u t
数组,限制为50(pthread\u t tid[50];
)。我有一个for循环,每次限制达到50时,pthread\u t
数组中的每个线程都会被终止
怎么做?我几乎测试了所有的东西。使用pthread_kill(tid[w],SIGKILL)代码>w是一个简单的循环控制变量,从0变为50。我已经测试了pthread_cancel(tid[w])代码>和问题继续存在
那么问题是什么呢?
每次我达到380个线程数时,我无法创建更多。但我要用取消或杀戮来杀人。那么发生了什么
该计划的目标是网络扫描仪。为了更快,我需要大约500个线程和大约2秒的超时时间来测试IP和端口
有人知道如何“绕过”这个问题吗?
我以为我可以杀死线程,这样可以解决问题,但我错了:(
在没有使用ulimit或in/proc/sys/kernel/threads\u max更改值的情况下,我查看了pthread\u attr\u setstacksize,但我有点困惑:p
有什么想法吗
编辑
请求的代码:P
我将把所有代码放在这里:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#ifndef SOL_TCP
#define SOL_TCP 6
#endif
#ifndef TCP_USER_TIMEOUT
#define TCP_USER_TIMEOUT 18 //retry
#endif
#define MAX_TH 250
struct ar_stc{
char* ip;
int port;
};
char* ret[2];
int porar[2];
pthread_t tid[MAX_TH];
void create_port_scan_th(char* host,int p,int j);
//cares about args.
//this is not helpful for the threads post on stackoverflow. skip this function
char** arguments_handle(int argc,char **arg)
{
char p[]="-p";
char h[]="-h";
size_t _p,_h;
_p=(size_t)strlen(p);
_h=(size_t)strlen(h);
if(argc!=5)
{
printf("Usage:./file -p PORT-RANGE -h HOST.IP\n");
exit(1);
}
if(strncmp(arg[1],p,_p)==0 || strncmp(arg[1],h,_h)==0 && strncmp(arg[3],p,_p)==0 || strncmp(arg[3],h,_h)==0)
{
if(strncmp(arg[1],p,_p)==0)
{
strncpy(ret[0],arg[2],strlen(arg[2]));
}
else
{
strncpy(ret[1],arg[2],strlen(arg[2]));
}
if(strncmp(arg[3],h,_h)==0)
{
strncpy(ret[1],arg[4],strlen(arg[4]));
}
else
{
strncpy(ret[0],arg[4],strlen(arg[4]));
}
}
return ret;
}
int* take_ports(char *arg)
{
char* ports[2];
ports[0] = malloc(5);
ports[1] = malloc(5);
memset(ports[0],0,5);
memset(ports[1],0,5);
char tmp[5];
int len = strlen(arg);
int i,j=0,x=0;
char min_p[5],max_p[5];
for(i=0;i<len;i++)
{
if(arg[i]=='-')
{
min_p[x]='\0';
j=1;
x=0;
continue;
}
else
{
if(j==0)
min_p[x]=arg[i];
else
max_p[x]=arg[i];
}
x++;
}
max_p[x]='\0';
porar[1]=atoi(max_p);
porar[0]=atoi(min_p);
free(ports[0]);
free(ports[1]);
return porar;
}
void *check_port(void* ar_p)
{
struct ar_stc *ar =ar_p;
char* ip = ar->ip;
int port = ar->port;
int s,conexao;
int timeout = 1000; //1 second timeout
s=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in dst;
setsockopt(s,SOL_TCP,TCP_USER_TIMEOUT,(char*)&timeout,sizeof(timeout)); //NOT WORKING :(
if(s<0)
{
printf("\nCouldnt create socket\nPremissions maybe?\n");
exit(1);
}
dst.sin_family = AF_INET;
dst.sin_port = htons(port);
dst.sin_addr.s_addr = inet_addr(ip);
bzero(&(dst.sin_zero),8);
//printf("\nChecking: %d...",port);
conexao = connect(s,(struct sockaddr*)&dst,sizeof(dst));
if(conexao <0)
{
printf("TCP/%d:CLOSED!\n",port); //just to make sure the thread is running
close(s);
return;
}
else
{
printf("TCP/%d:OPEN!\n",port);
close(s);
return;
}
}
int main(int argc, char **argv)
{
int open_ports[65535];
int open_ports_count=0;
int min_p,max_p;
int* p;
ret[0] = malloc(20);
ret[1] = malloc(20);
memset(ret[0],0,20);
memset(ret[1],0,20);
char** ipnport;
ipnport = arguments_handle(argc,argv);
printf("The IP is :%s and the range is %s\n",ipnport[1],ipnport[0]);
p=take_ports(ipnport[0]);
min_p=p[0];
max_p=p[1];
printf("Min port:%d e max port:%d\n",min_p,max_p);
int i;
int thread_count=-1;
for(i=min_p;i<=max_p;i++)
{
thread_count++;
create_port_scan_th(ipnport[1],i,thread_count);
if(thread_count>=MAX_TH)
{
sleep(1);
thread_count=0;
int w;
for(w=0;w<=MAX_TH;w++)
{
pthread_kill(tid[w],SIGKILL);
}
}
}
free(ret[0]);
free(ret[1]);
return 0x0;
}
void create_port_scan_th(char* host,int p,int j)
{
int error;
struct ar_stc *ar;
ar = malloc(sizeof(*ar));
ar->ip=host;
ar->port=p;
error = pthread_create(&(tid[j]),NULL,&check_port,(void*)ar);
if(error!=0)
printf("\nError creating thread:%s\n",strerror(error));
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#ifndef SOL_TCP
#定义SOL_TCP 6
#恩迪夫
#ifndef TCP\u用户\u超时
#定义TCP\u用户\u超时18//重试
#恩迪夫
#定义最大值250
结构钢筋混凝土{
字符*ip;
国际港口;
};
char*ret[2];
内孔[2];
pthread_t tid[MAX_TH];
无效创建端口扫描(字符*主机,int p,int j);
//关心args。
//这对stackoverflow上的线程post没有帮助。跳过此函数
字符**参数\句柄(int argc,字符**arg)
{
字符p[]=“-p”;
字符h[]=“-h”;
尺寸(t)(p),;
_p=(大小)斯特伦(p);
_h=(尺寸)斯特伦(h);
如果(argc!=5)
{
printf(“用法:./file-p PORT-RANGE-h HOST.IP\n”);
出口(1);
}
如果(strncmp(arg[1],p,_p)==0 | | strncmp(arg[1],h,_h)==0&&strncmp(arg[3],p,_p)==0 | | strncmp(arg[3],h,_h)==0)
{
if(strncmp(arg[1],p,_p)==0)
{
strncpy(ret[0],arg[2],strlen(arg[2]);
}
其他的
{
strncpy(ret[1],arg[2],strlen(arg[2]);
}
if(strncmp(arg[3],h,_h)==0)
{
strncpy(ret[1],arg[4],strlen(arg[4]);
}
其他的
{
strncpy(ret[0],arg[4],strlen(arg[4]);
}
}
返回ret;
}
int*take_端口(字符*arg)
{
字符*端口[2];
端口[0]=malloc(5);
端口[1]=malloc(5);
memset(端口[0],0,5);
memset(端口[1],0,5];
char-tmp[5];
int len=strlen(arg);
int i,j=0,x=0;
字符最小值p[5],最大值p[5];
对于(i=0;iip;
int port=ar->port;
int s,conexao;
int timeout=1000;//1秒超时
s=套接字(AF_INET,SOCK_STREAM,0);
dst中的结构sockaddr_;
setsockopt(s,SOL_TCP,TCP_USER_TIMEOUT,(char*)&TIMEOUT,sizeof(TIMEOUT));//不工作:(
如果
但我要用取消或杀戮来杀人
首先,pthread_kill不会终止线程。
(详见或)
如果向线程发送SIGKILL,整个过程将结束
要结束一个线程,您需要
使线结束
- 通过从线程函数返回,或
- 调用pthread_exit或
- pthread\u取消线程
通过以下方式处置绑定到线程的资源:
- 在线程上调用pthread_join(),或
- 使线成为分离的线
如果您通过使线程分离来选择最后一点-这将在线程结束时自动释放线程,您可以在线程函数的开始处调用pthread\u detach(pthread\u Self())
。
或者在调用pthread_create()时提供pthread_attr\t,将线程设置为分离状态
至于可以使用的线程总数,linux对任何用户可以运行的线程/进程总数都有限制
您可以使用命令ulimit-u
查看此信息。您的“ulimit-u”是380?ulimit-u是3376。经过一些更改。但是,是的,我只能创建380个线程。使用connect()进行端口扫描
是一种非常缓慢、嘈杂且效率低下的方法。您有什么理由需要使用这种方法吗?是的,速度很慢。这就是我需要修复超时的原因。我对原始套接字的了解不够。我可以使用SYN数据包并发送到n个端口。我知道这一点,但第一个小步骤是:)正确地(使用原始套接字)执行此操作将采取完全不同的方法-您现在所做的不会让您达到需要的位置。这几乎肯定是OPs问题-线程没有分离,也没有与pthread\u join()
连接,因此它们的资源不会释放。