ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Проблема с многопоточностью, C++
  #1  
Старый 25.09.2009, 17:31
mailbrush
Познавший АНТИЧАТ
Регистрация: 24.06.2008
Сообщений: 1,996
Провел на форуме:
6075534

Репутация: 2731


Отправить сообщение для mailbrush с помощью ICQ
По умолчанию Проблема с многопоточностью, C++

В общем интересуюсь этой проблемой уже давно. Пишу парсер аккаунтов одного форума. Пока тестовый, в 5 потоках надо отпарсить только 5 юзеов. Есть код
Код:
int uid = 1; //текущий айди юзера

void tfunc(void *argv)  
{
//здесь я создаю WinSock
sprintf( request, "GET /forum/profile.php?mode=viewprofile&u=%s HTTP/1.1\r\nHost: tfile.ru\r\nConnection: Close\r\n\r\n", IntToStr(uid).c_str()); //пишу в запрос id юзера 
//здесь завершаю работу WinSock
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
for(i=0;i<=4;i++)
{
uid++;
_beginthread(tfunc, 0, NULL); //старт потока
}
}
Проблема в том, что запрос отправляется всегда с айди = 5, т.е. с последним значением uid. Почему?
 
Ответить с цитированием

  #2  
Старый 25.09.2009, 17:40
Hiro Protagonist
Участник форума
Регистрация: 26.08.2009
Сообщений: 133
Провел на форуме:
193434

Репутация: 79
Отправить сообщение для Hiro Protagonist с помощью ICQ
По умолчанию

2mailbrush

а с чего ты взял, что потоки создадутся, запустятся и дойдут до sprintf сразу после _beginthread, там же ещё хренова туча crt мутотени выполнять? Есественно, что цикл выполняется быстрее, чем uid используется в потоке. В данном случае нужно синхронизировать потоки или передавать индивидуальные параметры по типу:

int *q = malloc(5*4);

for(i=0;i<=4;i++)
{
uid++;
q[i] = uid;
_beginthread(tfunc, 0, &q[i]);
}

free(q);

PS НЕ ИСПОЛЬЗУЙ _beginthread БОЛЬШЕ НИКОГДА!!! ОНА УСТАРЕЛА!!! ИСПОЛЬЗУЙ _beginthreadex.

Последний раз редактировалось Hiro Protagonist; 25.09.2009 в 17:55..
 
Ответить с цитированием

  #3  
Старый 25.09.2009, 18:04
Chrome~
Постоянный
Регистрация: 13.12.2008
Сообщений: 354
Провел на форуме:
1747641

Репутация: 175
Отправить сообщение для Chrome~ с помощью ICQ
По умолчанию

У меня раньше тоже была подобная проблема. Она решается путем блокировки переменной. В общем, я читал на блоге Kaimi статью от DX по работе с антикапчей. Если я не ошибаюсь, в статье такая проблема решается с помощью мьютексов.

http://kaimi.ru/2009/05/anticaptcha-assembler/

(ASM)

Последний раз редактировалось Chrome~; 25.09.2009 в 18:29..
 
Ответить с цитированием

  #4  
Старый 25.09.2009, 19:01
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

а вообще для таких целей есть интерлоковые функции которые юзаются внутри потока. типа такой:
Код:
int uid = 1; //текущий айди юзера

void tfunc(void *argv)  
{
int myID =  InterlockedIncrement(&uid) - 1;
//здесь я создаю WinSock
sprintf( request, "GET /forum/profile.php?mode=viewprofile&u=%i HTTP/1.1\r\nHost: tfile.ru\r\nConnection: Close\r\n\r\n", my_ID); //пишу в запрос id юзера 
//здесь завершаю работу WinSock
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
for(i=0;i<=4;i++)
{
_beginthread(tfunc, 0, NULL); //старт потока
}
}
т.е. значение переменной увеличивается на 1 через атомарный доступ к памяти. т.е. происходит блокировка шины памяти, то даже на многопроцессорных системах всё будет пахать офегительно.

К томуже IntToStr(uid).c_str() смысл юзать? или можно с шаблоне задать %i или %u
 
Ответить с цитированием

  #5  
Старый 25.09.2009, 20:20
Hiro Protagonist
Участник форума
Регистрация: 26.08.2009
Сообщений: 133
Провел на форуме:
193434

Репутация: 79
Отправить сообщение для Hiro Protagonist с помощью ICQ
По умолчанию

2slesh

Интерлокед конечно быстрые, да и в большинстве случаев синхронизация концептуальнее более правильна, но имхо в брутерах-парсерах многопоточных лучше инициализировать все заранее + использовать пулы потоков (+ асинхронный I/O). Тогда к моменту исполнения непосредственно функционала не надо будет тратится на создания потоков (тысячи тактов) и/или синхронизацию (от десятков до сотен тактов). Выйгрышь в производительности существеннен, оссобенно при количестве потоков более 2*кол-во_процессоров. Вышесказанное естественно ИМХО.
 
Ответить с цитированием

  #6  
Старый 25.09.2009, 20:40
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

всё это правильно, но ты забыл про одно - скорость сети - ничтожна по сравнению с пропускной способностью шины памяти и скорости работы проца.
Так что как никрути но всё равно упрешся в скорость сети. И эти все затраты будут незаметны.

темболее что если ты не заметил то интерлок функции состоят примерно из 3-4 машинных команд. и такая синхронизация никаких затрат не вызывает.
банальный тест:
на проце E5200 (2 ядра 2,5 ГГц)
10 миллионов вызовов InterlockedIncrement
занимают ~156 микросекунд. так что за 1 микросекунду эту будет примерно 64 тысячи раз.
При этом если учеть что идеальаня скорость инета - 100 мегобит / с то выходит что за 1 микросекунду максимум ты пошлеш только 12500 байт. Это только посылка.
Сам понимаеш такой инет мало у кого есть. а вот такие процы есть у всех.
так что сейчас как никрути но всё только в сеть упирается. единственное что для брута нужно - выделенная память для буферов - вот это реально критично. потому что выделение памяти - процес довольно медленный. Потому что 10 тысяч выделений памяти по 64 кила. занимает времяни больше 1 секунды.

Да и брутеры не нужнаются в такой скорости по причине того что тебя быстрее забанять на серваке )

Другое дело - управление сетевыми приложениями или ботнетами. вот тут вот нагрузка довольно большая идет, но и то с ней достаточно весомо справляется проц. а вот канал уже дохнет

Последний раз редактировалось slesh; 25.09.2009 в 20:55..
 
Ответить с цитированием

  #7  
Старый 25.09.2009, 20:49
Hiro Protagonist
Участник форума
Регистрация: 26.08.2009
Сообщений: 133
Провел на форуме:
193434

Репутация: 79
Отправить сообщение для Hiro Protagonist с помощью ICQ
По умолчанию

2slesh

все мы стремимся к идеалу )) поэтому и пишем shl eax, 1 вместо mul, хотя вызовы API сотрут различия )) тем более не стоит забывать, что при увеличении числа потоков прога станет быстрее (в смысле в работе на хосте) за счет того, что все тяжелые операции мы сделаем заранее. ИМХО ^____^
 
Ответить с цитированием

  #8  
Старый 25.09.2009, 20:52
mailbrush
Познавший АНТИЧАТ
Регистрация: 24.06.2008
Сообщений: 1,996
Провел на форуме:
6075534

Репутация: 2731


Отправить сообщение для mailbrush с помощью ICQ
По умолчанию

Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <process.h>
#include <stdio.h>
#include <winsock2.h>
#include <iostream>
#include <string>
#include <vector>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "sSkinManager"
#pragma link "sSkinProvider"
#pragma resource "*.dfm"

TForm1 *Form1;
volatile long uid = 1;
char mystring [1024];
CRITICAL_SECTION cs;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
int i;



void tfunc(void *argv)
{
int myID =  InterlockedIncrement(&uid) - 1;
char request[1024*5], response[1024*5];
int first, second;
char* headers;

sockaddr_in s_a;
WSADATA wd;
WSAStartup( MAKEWORD( 2, 2 ), &wd );

while(myID<15)
{
SOCKET s = socket( AF_INET, SOCK_STREAM, 0 );
if (s == INVALID_SOCKET)
ShowMessage("INVALID");
s_a.sin_addr.s_addr = inet_addr( "89.188.109.206" );
s_a.sin_port = htons( 80 );
s_a.sin_family = AF_INET;
if (connect( s, (struct sockaddr*)&s_a, sizeof( s_a ) ) == SOCKET_ERROR)
ShowMessage("Bad Connect!");
sprintf( request, "GET /forum/profile.php?mode=viewprofile&u=%i HTTP/1.1\r\nHost: tfile.ru\r\nConnection: Close\r\n\r\n", myID);
send( s, request, strlen( request ), 0 );
//EnterCriticalSection( &cs );
for(i=0;i<=4;i++)
recv( s, response, 1024 , 0 );
//LeaveCriticalSection( &cs );
closesocket( s );
}
WSACleanup(); //
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
InitializeCriticalSection( &cs );
for(i=1;i<=5;i++)
{
_beginthread(tfunc, 0, NULL);
}
}
//---------------------------------------------------------------------------







void __fastcall TForm1::Button2Click(TObject *Sender)
{
ShowMessage("hello");
}
//---------------------------------------------------------------------------
Вобщем вот весь код... Теперь я хочу, чтобы каждый поток своего юзера парсил, но что я только не плюсовал, чтобы айди увеличивался - ничего не помогает. Все потоки парсят 1-5 юзера. Да и с цикла while() не выходит...
 
Ответить с цитированием

  #9  
Старый 25.09.2009, 20:57
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

WSAStartup - делается только в начале проги и тока 1 раз
WSACleanup - только в конце проги. Так что таким видом ты можеш заглючить прогу
 
Ответить с цитированием

  #10  
Старый 25.09.2009, 21:01
mailbrush
Познавший АНТИЧАТ
Регистрация: 24.06.2008
Сообщений: 1,996
Провел на форуме:
6075534

Репутация: 2731


Отправить сообщение для mailbrush с помощью ICQ
По умолчанию

Цитата:
Сообщение от slesh  
WSAStartup - делается только в начале проги и тока 1 раз
WSACleanup - только в конце проги. Так что таким видом ты можеш заглючить прогу
Ок, но как решить проблему, которую я описал выше?
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с дедиками [help!] Sniper482 Безопасность 4 14.09.2009 21:22
Непонятная проблема с интернетом по всей локалке ZneP Администрирование 6 19.06.2009 15:27
Проблема отключения служб!!! Snap Безопасность 3 10.02.2009 15:12
проблема RocketV1_0 КИРЮХА ! Схемы и программы 0 10.06.2006 23:48
Проблема Mac OS X не только в Safari DRON-ANARCHY Мировые новости 0 23.02.2006 21:12



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ