Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Опять вопросы про _beginthreadex / 12 сообщений из 12, страница 1 из 1
07.10.2014, 14:44
    #38769146
vadipok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Добрый день, коллеги!

Нужна помощь!!
Создал структуру IPADDRESS, а потом прикрутил его в вектор ipAddress_vec.
Там где 111...1 я его заполняю.
Там где 222...2 пытаюсь его запустить функцию getDataCPU в нескольких потоках через _beginthreadex, в зависимости от того, сколько элементов в ipAddress_vec.
В функции getDataCPU происходит простой вывод на экран, и тут проблема становится очевидной.
Выводит на экран только последний элемент вектора для всех 3-х случаев.
(Смотри прин-скрин командной строки.)
Гугление не помогает.
Как быть? Что делать?

Спасибо большое!

Переменные:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
struct IPADDRESS
{
	int   employeeID;
	char* ipAddress;
	int   step;
};

vector <IPADDRESS> ipAddress_vec;

IPADDRESS ipAddressStrucIn;
IPADDRESS ipAddressStrucOut;
IPADDRESS* ipAddressStruct = (IPADDRESS*)malloc(sizeof(IPADDRESS));



Кусок кода main:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
		ResultSet *rs = stmt->executeQuery();
		while (rs->next())
			  {
			  ipAddressStrucIn.employeeID = rs->getInt (1);
			  t1  = rs->getInt (2);
			  t2  = rs->getInt (3);
			  t3  = rs->getInt (4);
			  t4  = rs->getInt (5);
			  ss << t1 << "." << t2 << "." << t3 << "." << t4;
			  t = ss.str();
			  ipAddressStrucIn.ipAddress = strdup(t.c_str());

			  ipAddress_vec.push_back(ipAddressStrucIn);

			  cout << ipAddressStrucIn.ipAddress << endl;
			  cout << ipAddressStrucIn.employeeID << endl;

			  //clear
			  ss.str(std::string());
			  ss.clear();
			  t.clear();
		  

			  }

		cout << "11111111111111111111111111111111" << endl;

		//const *int threadSize = (int) ipAddress_vec.size();

		HANDLE threads[1000];

		for (d=0;d<(int) ipAddress_vec.size();d++) {
			ipAddressStrucOut = ipAddress_vec[d];
			cout << "22222222222222222222222222222222" << endl;
			ipAddressStruct->employeeID = ipAddressStrucOut.employeeID;
			ipAddressStruct->ipAddress = ipAddressStrucOut.ipAddress;
			ipAddressStruct->step = d;

			threads[d] = (HANDLE)_beginthreadex(NULL,0,&getDataCPU, (void *) ipAddressStruct,0,NULL);
		}

		Sleep(5000);

		// пробовал, не помогло
		//WaitForMultipleObjects(1000, threads, true, INFINITE);

		for(d=0;d<ipAddress_vec.size();d++) {
			cout << "33333333333333333333333333333" << endl;
			WaitForSingleObject( threads[d], INFINITE );
			CloseHandle(threads[d]);
		}



getDataCPU:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
unsigned __stdcall getDataCPU( void* pArguments )
{
	cout << "44444444444444444444444444444444" << endl;
	IPADDRESS *ipAddress2 = static_cast<IPADDRESS*>(pArguments);
	cout << ipAddress2->employeeID <<endl;
	cout << ipAddress2->ipAddress  <<endl;
	cout << ipAddress2->step  <<endl;
	cout << GetCurrentThreadId() << endl;
	_endthreadex( 0 );

    return 0;   // Program successfully completed.
}
...
Рейтинг: 0 / 0
07.10.2014, 14:59
    #38769176
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Классическая ошибка. Вызов:
Код: plaintext
1.
_beginthreadex(NULL,0,&getDataCPU, (void *) ipAddressStruct,0,NULL);


не означает что выполнится и потом выйдет из beginthreadex() и пойдет дальше
Код: plaintext
1.
IPADDRESS *ipAddress2 = static_cast<IPADDRESS*>(pArguments);



реально происходит так первый поток вызывает несколько раз beginthreadex(), а уже потом созданные потоки выполняют чтение pArguments, в котором первый поток видит то что предназначено не ему, а последующим.

PS Запутался в твоих указателях, как подправить не скажу, передавай в параметрах адрес структуры, а не адрес указателя на структуру.
...
Рейтинг: 0 / 0
07.10.2014, 15:14
    #38769198
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Помедитируй над этим кодом
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
unsigned __stdcall thread( void* pArguments )
{
	int j = *(int*)pArguments;
	printf("%d\n", j);
	_endthreadex( 0 );
    return 0;   // Program successfully completed.
}

int main( void )
{
	for(int i = 0; i < 4; i++)
	{
		_beginthreadex(NULL,0,&thread, (void *) &i,0,NULL);
		//Sleep(100);
	}
	Sleep(5000);
}



Попробуй Sleep(100); разремить
...
Рейтинг: 0 / 0
07.10.2014, 15:20
    #38769212
vadipok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Dima T,

На моем примере помогло, спасибо!

Но в реальном примере функция getDataCPU намного больше и работает для некоторых IP-ишников на порядок дольше(может быть до минуты).
Час попробую функцию getDataCPU вернуть в реальное состояние.
...
Рейтинг: 0 / 0
07.10.2014, 15:28
    #38769233
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
vadipokНа моем примере помогло, спасибо!
Я у Sleep(100) поставил не для того чтобы ты его к себе скопипастил
Добейся чтоб мой пример работал корректно без слипа. Повторяю проблема в том что передается указатель на i, а в момент чтения по адресу этого указателя в i совсем другое значение.
...
Рейтинг: 0 / 0
07.10.2014, 15:30
    #38769240
vadipok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Dima TvadipokНа моем примере помогло, спасибо!
Я у Sleep(100) поставил не для того чтобы ты его к себе скопипастил
Добейся чтоб мой пример работал корректно без слипа. Повторяю проблема в том что передается указатель на i, а в момент чтения по адресу этого указателя в i совсем другое значение.

, работает же
...
Рейтинг: 0 / 0
07.10.2014, 15:35
    #38769255
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
vadipok, работает же
Подумай как работает:
Запускается 1-й поток, пауза 100 мс (за это время он уже завершается), второй, пауза и т.д.
быстрее будет по очереди thread() вызвать 4 раза, последовательно без пауз и лишних потоков
т.е. так
Код: plaintext
1.
2.
3.
4.
	for(int i = 0; i < 4; i++)
	{
		thread(&i);
	}
...
Рейтинг: 0 / 0
07.10.2014, 15:42
    #38769276
vadipok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Dima Tvadipok, работает же
Подумай как работает:
Запускается 1-й поток, пауза 100 мс (за это время он уже завершается), второй, пауза и т.д.
быстрее будет по очереди thread() вызвать 4 раза, последовательно без пауз и лишних потоков
т.е. так
Код: plaintext
1.
2.
3.
4.
	for(int i = 0; i < 4; i++)
	{
		thread(&i);
	}



Да я это понял, только пока не знаю как.
Работаю на этим.
...
Рейтинг: 0 / 0
07.10.2014, 17:53
    #38769491
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
vadipok, работает же
Это можно распечатать и на стенку повесить.
...
Рейтинг: 0 / 0
07.10.2014, 18:47
    #38769561
vadipok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Решил я проблему, возможно не очень красиво. )

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
		HANDLE hThread;
		HANDLE threads[1000];
		SECURITY_ATTRIBUTES  sa = {sizeof(SECURITY_ATTRIBUTES), 0, TRUE};

		for (d=0;d<(int) ipAddress_vec.size();d++) {
			unsigned threadId;
			
			threads[d] = (HANDLE)_beginthreadex(&sa, 4096, &getDataCPU, (void *) d, 0, &threadId);
			
			//Sleep(100);
		}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
unsigned __stdcall getDataCPU( void* pArguments )
{
	cout << (int) pArguments << endl;
	int step = (int) pArguments;
	IPADDRESS ipAddress = ipAddress_vec[step];
	//IPADDRESS *ipAddress2 = static_cast<IPADDRESS*>(pArguments);
	cout << ipAddress.employeeID <<endl;
	cout << ipAddress.ipAddress  <<endl;
	//cout << ipAddress2->step  <<endl;
	cout << GetCurrentThreadId() << endl;
}



Основной смысл в том, что не передаю всю структуру, а только номер шага. Потом вытаскиваю от вектора.

Следующий вопрос остается открытым, как дождаться, чтобы все процессы завершились?
Следующего кода явно не достаточно(Над решением Sleep уже посмеялись ):
Код: plaintext
1.
2.
3.
4.
		for(d=0;d<ipAddress_vec.size();d++) {
			WaitForSingleObject( threads[d], INFINITE );
			CloseHandle(threads[d]);
		}
...
Рейтинг: 0 / 0
07.10.2014, 19:31
    #38769607
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
vadipokРешил я проблему, возможно не очень красиво. )
Правильно решил.

vadipokСледующий вопрос остается открытым, как дождаться, чтобы все процессы завершились?
Следующего кода явно не достаточно
Код: plaintext
1.
2.
3.
4.
		for(d=0;d<ipAddress_vec.size();d++) {
			WaitForSingleObject( threads[d], INFINITE );
			CloseHandle(threads[d]);
		}


Замени это на
Код: plaintext
1.
2.
3.
4.
WaitForMultipleObjects(ipAddress_vec.size(), threads, true, INFINITE);
		for(d=0;d<ipAddress_vec.size();d++) {
			CloseHandle(threads[d]);
		}


Заметь: скопипастил из твоего первого поста

PS учи матчасть (читай хэлпы), т.е. что конкретно делает каждая вызываемая тобой функция. Если будешь гадать как сейчас - ничего хорошего не выйдет.
...
Рейтинг: 0 / 0
08.10.2014, 09:28
    #38769913
vadipok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять вопросы про _beginthreadex
Dima T,

Спасибо, топик можно закрывать.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Опять вопросы про _beginthreadex / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]