0

ここで少し問題があります。Linux が実際に実行できるユーザーのスレッド数を制限していることは知っています。

私が使用しているのは、50 ( )pthread_createの制限付きの配列です。その制限が50に達するたびに、アレイ上のすべてのスレッドが強制終了されるforサイクルがあります。pthread_tpthread_t tid[50];pthread_t

どのように?私はほとんどすべてをテストしました。with pthread_kill(tid[w],SIGKILL);w は、0 から 50 までの単純なサイクル制御変数です。既にテストpthread_cancel(tid[w]);しましたが、問題は解決しません。

それで、問題は何ですか?スレッド数が 380 に達するたびに、それ以上作成できなくなります。しかし、キャンセルまたはキルで殺しています。それで、何が起こっているのですか?

プログラムの目的は、ネットワーク スキャナーです。高速化するには、IP とポートをテストするために 2 秒程度のタイムアウトで 500 スレッド程度が必要です。

この問題を「回避」する方法を知っている人はいますか? 私は問題を解決するスレッドを殺すことができると思ったが、私は間違っていた:(

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));
}
4

1 に答える 1

1

しかし、キャンセルまたはキルで殺しています。

まず第一に、pthread_kill はスレッドを強制終了または終了しません。(詳細については、pthread_kill doesn't kill thread C linuxまたはWhen to use pthread_cancel and not pthread_kill を参照してください)。

SIGKILL をスレッドに送信すると、プロセス全体が終了します。

スレッドを終了するには、次のことが必要です

  1. スレッドを終了します。

    • スレッド関数から戻るか、または
    • pthread_exit を呼び出すか、
    • pthread_スレッドをキャンセルする
  2. 次の方法で、スレッドに関連付けられているリソースを破棄します。

    • スレッドで pthread_join() を呼び出すか、
    • スレッドを分離スレッドにします。

スレッドをデタッチして最後のポイントを選択すると、スレッドが終了すると自動的にスレッドが解放さpthread_detach(pthread_Self())れ、スレッド関数の開始時に呼び出すことができます。または、pthread_create() を呼び出すときに pthread_attr_t を指定して、スレッドを切り離された状態に設定します。

使用できるスレッドの総数に関しては、Linux では、ユーザーが実行できるスレッド/プロセスの総数に制限があります。

コマンドでこれを表示できますulimit -u

于 2013-11-06T23:52:36.363 に答える