powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Опять вопросы про _beginthreadex
12 сообщений из 12, страница 1 из 1
Опять вопросы про _beginthreadex
    #38769146
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, коллеги!

Нужна помощь!!
Создал структуру 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
Опять вопросы про _beginthreadex
    #38769176
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Классическая ошибка. Вызов:
Код: plaintext
1.
_beginthreadex(NULL,0,&getDataCPU, (void *) ipAddressStruct,0,NULL);


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



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

PS Запутался в твоих указателях, как подправить не скажу, передавай в параметрах адрес структуры, а не адрес указателя на структуру.
...
Рейтинг: 0 / 0
Опять вопросы про _beginthreadex
    #38769198
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помедитируй над этим кодом
Код: 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
Опять вопросы про _beginthreadex
    #38769212
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

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

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

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



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

Код: 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
Опять вопросы про _beginthreadex
    #38769607
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Опять вопросы про _beginthreadex
    #38769913
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

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


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