LINUX.ORG.RU

Помогите разобраться с потоками


0

0

Попал мне в руки как-то журнал хакер(мерзкий конечно,но бывает и там полезная инфа =) ) и там описывалась идея создания многопоточного сканера и я решил реализовать это на C в качестве упражнения по многозадачности и сети(это первые опыты,так что сильно не бейте.).

Пока что получилось вот что:

#include<sys/socket.h> #include<sys/types.h> #include<resolv.h> #include<stdio.h> #include<errno.h> #include<glib.h> #include<pthread.h> #include<signal.h>

#define PROCNUM 30

GList* ips; // список ip-шников

void generate_ips() { int i; for(i=1;i<255;i++) ips=g_list_append(ips,g_strdup_printf("192.168.22.%d",i)); }

void* try_ip(void* ip) { int sock; struct sockaddr_in server; memset(&server,sizeof(server),0);

server.sin_family=AF_INET; server.sin_port=htons(139); server.sin_port=htons(139); inet_aton(ip,&server.sin_addr); sock=socket(PF_INET,SOCK_STREAM,0);

if(sock<0){ printf("error %d while creating socket!\n",errno); exit(1); }

if(connect(sock,&server,sizeof(server))==0){ printf("==>%s\n",ip); close(sock); } raise(SIGCHLD); return NULL; }

void on_child_exited(int sig) { if(ips) { pthread_t child; if((pthread_create(&child,NULL,&try_ip,(void*)(ips->data)))!=0){ printf("error creating thread!\n"); } ips=ips->next; } }

int main(int argc,char* argv[]) { int ips_in_scan=0;

struct sigaction act; memset(&act,sizeof(act),0);

act.sa_handler=on_child_exited; act.sa_flags=SA_NOMASK | SA_RESTART; //не уверен с флагами sigaction(SIGCHLD,&act,0);

generate_ips(); for(;ips,ips_in_scan<PROCNUM;ips=ips->next,ips_in_scan++) { pthread_t child; if((pthread_create(&child,NULL,&try_ip,(void*)(ips->data)))!=0) { printf("error creating thread!\n"); } } sleep(100); return 0; }

Идеология следующая: сначала генерю список ip,потом начинаю его читать и создаю максимально возможное число потоков.Далее я хочу чтобы как только потомок отработает,приходил сигнал родителю и он стартовал новый поток,пока есть что сканить.Результаты потомки отдают в stdin.

Наткнулся на следующие проблемы:

1) После того как я создал первые n потоков,родителю больше нечего делать и он выходит.Во всех примерах,какие у меня были там бы вызывался waitpid(),но я не знаю pid`a того потомка,которого мне надо ждать,так как он может даже ещё не начат...

2) Как сделать timeout на процедуру connect() ? Чтобы если скажем через 5 секунд если потомок не вышел,убить его нафиг и продолжить со следующим адресом..

3) В обработчике сигнала возможно нужна блокировка доступа к списку?

4) Нужны либо какие действия по очистке после завершения потомка? я что-то так и не догнал...

5) И что происходит с теми потомками,которые не завершились,а родитель вышел без waitpid и т.п. ? zombie или как ? я что-то пока не заметил никакого эффекта в ps после запуска существующей версии..

Помогите пжалста :) ! а то я что-то совсем запутался.Если есть какие-нибудь хорошие ссылки по теме - кидайте.И ещё - может я с самого начала выбрал неправильную идеологию?

anonymous
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.