Потоки

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by 97mik, 29 Sep 2013.

  1. 97mik

    97mik New Member

    Joined:
    8 Jan 2012
    Messages:
    8
    Likes Received:
    0
    Reputations:
    0
    Работаю с сайтом в несколько потоков, когда появляется капча, то она появляется на всех потоках, и со всех потоков надо разгадывать, а как сделать так, чтобы на одном потоке разгадало, а все остальные просто обновили страницу?
     
  2. 97mik

    97mik New Member

    Joined:
    8 Jan 2012
    Messages:
    8
    Likes Received:
    0
    Reputations:
    0
    Не, с куки нельзя.
     
  3. 97mik

    97mik New Member

    Joined:
    8 Jan 2012
    Messages:
    8
    Likes Received:
    0
    Reputations:
    0
    Прокси не к чему, а только ради капчи - напряжно.
     
  4. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Не новость и в каждой теме про многопоточность пишу, что количество потоков должно ровняться количеству ядер на данном компьютере. Если потоков больше нет никакого эффекта ускорения, лишь трата процессорных ресурсов на переключения контекста потока. http://goo.gl/hIAue

    Так что если это у тебя не распределенная система, не заморачивайся с синхронизацией.
     
    _________________________
    GoodBoy and makag like this.
  5. noxjoker

    noxjoker Member

    Joined:
    7 Aug 2009
    Messages:
    189
    Likes Received:
    24
    Reputations:
    0
    Gar|k все верно говоришь, но это лишь для вычислительных операций.


    97mik насколько я понял тебе нужно сделать так:
    1. Ты заходишь на сайт в 1 потоке, например.
    2. Получаешь, Куки и рассылаешь всем потокам.
    3. Потоки делают действие, которые вызывают капчу.
    4. Определение капчи и блокирование всех потоков пока не введется капча.
    5. После ввода восстановление работы всех потоков.

    Это решается с помощью семафоров.
     
    #5 noxjoker, 30 Sep 2013
    Last edited: 30 Sep 2013
    GoodBoy likes this.
  6. antichar

    antichar New Member

    Joined:
    11 Sep 2013
    Messages:
    45
    Likes Received:
    2
    Reputations:
    0
    Все правильно, для сетевых дел без многопоточности никуда.
    To ТС: используй cookies и/или прокси, или опиши задачу нормально.
     
  7. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    WendM, параллельно эти задачи выполнятся все равно не будут, как ни крути.
    antichar, если пишешь на блокируемых сокетах... и нужно ЖДАТЬ ответа от сервера.
    Последнее время везде где можно, стараюсь использовать не блокируемые сокеты и асинхронную модель.

    По сути если не нужна проверка результата, можно создавать одно HTTP1/1 keep-alive соединение, и посылать туда в цикле POST запросы пока соединение активно и не закрыто сервером.

    Ну уж если отходить от основной темы, не стоит забывать о том что
    о том что
    И надо помнить о том что сетевое программирование, не такое простое, как кажется на первый взгляд, в нем ОЧЕНЬ много различных нюансов.
    Читайте умные книжки, рекомендую "Эффективное программирование TCP/IP" Йон Снейдер, но не стоит забывать что технологии не стоят на месте и в моде асинхронность и epoll.

    Сорри за оффтоп.
     
    _________________________
    #7 Gar|k, 30 Sep 2013
    Last edited: 30 Sep 2013
    1 person likes this.
  8. antichar

    antichar New Member

    Joined:
    11 Sep 2013
    Messages:
    45
    Likes Received:
    2
    Reputations:
    0
    Да, это я и имел в виду.
     
  9. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Gar|k Вообще не в тему. Ты забыл на каком ты сайте? Тут пишут всякие парсеры, регалки и думают как формочку ручками создать. Из-за этого:
    Практически всегда нужно определять результат.
    Ну естественно блокируемые сокеты, т.к. Indy по другому не может.
    Все конечно верно, для винды асинхронные режим родной. Но что бы правильно реализовать сетевое взаимодействие на IOCP нужно достаточно много знать и потом писать свою обертку over 5-6k строк HTTP протокола, при том надо знать еще больше. И из всех этих кошмаров профиту для регалок, парсеров, ботов не будет вообще.
    А теперь посмотрим на среднестатисчиского обывалу этого форума в этом разделе, ну конечно же такие вещи не просто нужно, а необходимо советовать.
     
  10. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    199
    Likes Received:
    12
    Reputations:
    1
    Gar|k, все зависит от реализации. Возьмем брутфорс любой. Запускаешь 3 потока на одном ядре, каждый из них запускает свой запрос HTTP (к примеру). Пока первый отослал и не получил ответ, второй и третий уже тоже отослали. Потом ответ пришел первому, после второму и третьему. А если у тебя один поток, то ты будешь посылать запросы по очереди и ждать дольше.

    ОС переключает контекст процессора не на уровне сетевых запросов TCP. Поэтому получается эффективнее.

    Если все еще сомневаешься, попробуй сам. Только все зависит больше не от ОС и количества ядер, а от того как ты их используешь.
     
  11. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    В винде достаточно сделать пустое окошко и ловить на него.

    Code:
    int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) 
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
    	WSADATA ws;
    	if (NO_ERROR != WSAStartup(0x202, &ws))
    		return EXIT_FAILURE;
    
    	hInst=hInstance;
    
    	WNDCLASS WndClass={ sizeof(WndClass) };
    	TCHAR szClassName[]=_TEXT("RemoteTouch 0.1");
    	WndClass.lpszClassName=szClassName;
    	WndClass.lpfnWndProc=GarikWinProc;
    
    	if(RegisterClass(&WndClass))
    	{
    		HWND hWnd=CreateWindow(szClassName,NULL,0,0,0,0,0,NULL,NULL,hInstance,lpCmdLine);
    		if(NULL != hWnd) 
    		{
    			MSG Msg;
    			BOOL fGotMessage;
    
    			while ((fGotMessage = GetMessage(&Msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1) 
    			{ 
    				TranslateMessage(&Msg); 
    				DispatchMessage(&Msg); 
    			} 
    		}
    	}
    
    	WSACleanup();
    
    	return EXIT_SUCCESS;
    }
    
    BOOL StartServer(HWND hWnd)
    {
    	if(INVALID_SOCKET != sServerListen)
    		closesocket(sServerListen);
    
    	sServerListen = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    	if ( INVALID_SOCKET != sServerListen )
    	{
    		int on=1;
    		if(SOCKET_ERROR != setsockopt(sServerListen,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on)))
    		{
    			struct sockaddr_in localaddr;
    			localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    			localaddr.sin_family = AF_INET;
    			localaddr.sin_port = htons(options.port);
    
    			if (SOCKET_ERROR != bind(sServerListen, (struct sockaddr *)&localaddr, sizeof(localaddr)))
    			{
    				if(SOCKET_ERROR != WSAAsyncSelect(sServerListen,hWnd,WM_SOCKET,FD_READ))
    				{
    					return TRUE;
    				}
    			}
    		}
    	}
    
    
    	return FALSE;
    }
    
    LRESULT CALLBACK GarikWinProc(HWND hWnd,UINT Message, UINT wParam, LONG lParam) 
    {
    
    	switch(Message)
    	{
    	case WM_SOCKET:
    		{
    			switch (WSAGETSELECTEVENT(lParam))
    			{
    			case FD_READ:
    				break;
    			}
    			return 0;
    		}
    	case WM_CREATE: 
    		{
    			StartServer(hWnd);
    			return 0; 
    		}
    
    	case WM_DESTROY:
    
    		if(INVALID_SOCKET != sServerListen)
    			closesocket(sServerListen);
    
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hWnd,Message,wParam,lParam);
    }
    
     
    _________________________
  12. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,296
    Reputations:
    327
    эффект ускорения еще какой, например один поток логинится на один сайт, другой на другой и тд.
    вот еслибы эти потоки жрали 100% юзермодного времени ( какойнить цикл без вызова апей, например ченить в памяти считал итд) - тогда смысла делать их больше чем ядер - действительно нет, но это тоже спорный вариант - смотря какая задача стоит - может мне надо чтоб "одновременно" 16 участков памяти обрабатывались итд
     
  13. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Товарищи, как видно большинство не в курсе, но многопоточность != асинхронность.
    Snow на это намекает в своем посте, остальные несчадно смешивают оба этих понятия.
     
  14. notkeo

    notkeo New Member

    Joined:
    24 Dec 2011
    Messages:
    17
    Likes Received:
    0
    Reputations:
    0
    Собственно, как ни странно, но при взаимодействии с сетью, число потоков большее, чем число ядер дает большую эффективность. Тут скорей надо рассчитывать количество тредов уже исходя из пропускного канала.

    К вопросу ТС - должен быть создан некий класс-менеджер потоков. Потоки ничего не должны знать об выполняемой задаче, они только выполняют то, что дает класс-менеджер. Каждый из потоков должен возвращать результат выполненной работы, а класс-менеджер в свою очередь решать что с этим делать - появилась капча ? зарядить 1 поток на разгадывание, затем продолжить работу.

    Однако все это слишком сложно для школьников с их парсерами в 1.5 класса со сногшибательным применением ООП.
     
  15. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Не совсем, если заморочиться, то Gar|k прав. Хватит ровно столько потоков, сколько ядер, но тут надо использовать асинхронный режим, причем не через привязку к окну, а через привязку к порту завершения.
     
  16. notkeo

    notkeo New Member

    Joined:
    24 Dec 2011
    Messages:
    17
    Likes Received:
    0
    Reputations:
    0
    Понятия не имею о чём ты.
    Перед тем как написать сюда, сделал небольшой пример на Java, в котором грузился асинхронно 20 раз vk.com с 8 потоков (8 ядер) и с 20 потоков. Время загрузки как раз было в 2.5 меньше.
     
  17. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    При работе с сетью на асинхронных сокетах (как и при работе с файлами), увеличение количества тредов не даст увеличения скорости независимо от количества ядер. Здесь очевидно, где узкое место.
    По той же причине однопоточный софт на асинхронных сокетах при автоматизации работы с сайтами не будет работать быстрее софта на синхронных с количеством тредов, значительно превышающим количество ядер.
    Оптимальное решение зависит от конкретной задачи, универсального быть не может. Поэтому нельзя говорить, что сокеты должны быть всегда асинхронными, а количество тредов должно быть равным количеству ядер.
    При работе с HTTP использование синхронных сокетов и большого количества тредов вполне оправдано, так как некритичное увеличение скорости работы, пусть даже на 1%, не оправдывает значительное усложнение разработки софта.