gpt4 book ai didi

c - 如何 "bypass"pthreads限制数量

转载 作者:太空宇宙 更新时间:2023-11-04 11:18:17 24 4
gpt4 key购买 nike

我这里有个小问题。我知道 Linux 限制了用户实际可以运行的线程数。

我正在使用 pthread_create 和一个限制为 50 ( pthread_t tid[50]; ) 的 pthread_t 数组。我有一个 for 循环,每次限制达到 50 时,pthread_t 数组上的每个线程都会被杀死。

如何?我测试了几乎所有的东西。 with pthread_kill(tid[w],SIGKILL); w 是一个从 0 到 50 的简单循环控制变量。我已经测试过 pthread_cancel(tid[w]); 和问题一直存在。

那么问题是什么?每次我达到 380 个线程数时,我都无法创建更多。但我正在用取消或杀死来杀死。那么发生了什么?

该程序的目标是网络扫描仪。为了更快,我需要大约 500 个线程和大约 2 秒的超时时间来测试 IP 和端口。

有谁知道如何“解决”这个问题?我以为我可以杀死线程来解决问题,但我错了:(

在不使用 ulimit 或/proc/sys/kernel/threads_max 更改值的情况下,我查看了 pthread_attr_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));
}

最佳答案

But I'm killing with cancel or kill.

首先,pthread_kill 不会杀死或结束线程。(更多信息见 pthread_kill doesnt kill thread C linuxWhen to use pthread_cancel and not pthread_kill)。

如果你向一个线程发送SIGKILL,整个过程就会结束。

要结束一个线程,你需要

  1. 使线程结束。

    • 从线程函数返回,或者
    • 调用 pthread_exit 或
    • pthread_cancel 线程
  2. 通过以下方式释放绑定(bind)到线程的资源:

    • 在线程上调用 pthread_join() 或
    • 使线程成为分离线程。

如果您通过使线程分离来选择最后一点 - 这将在线程结束时自动释放线程,您可以在线程函数的开头调用 pthread_detach(pthread_Self())。或者在您调用 pthread_create() 时提供 pthread_attr_t,您可以在其中将线程设置为分离状态。

至于您可以使用的线程总数,Linux 对任何用户可以运行的线程/进程总数有限制。

可以用ulimit -u命令查看

关于c - 如何 "bypass"pthreads限制数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19825180/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com