powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как передать строковый параметр в CreateThread?
32 сообщений из 32, показаны все 2 страниц
Как передать строковый параметр в CreateThread?
    #38407751
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Контекст кода примерно такой:

Код: 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.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
...
    case WM_COPYDATA:
      cout << "WM_COPYDATA" << endl;
      COPYDATASTRUCT* pcds;
      pcds = (COPYDATASTRUCT*)lparam;
      } else if (pcds->dwData == 100) {//тест запрос

        DWORD dwThreadId;
        HANDLE hThread;
        hThread = CreateThread(
         NULL,         // атрибуты безопасности по умолчанию
         0,            // размер стека используется по умолчанию
         ThreadFunc_Answer,   // функция потока
         pcds->lpData, // чего я тут только не перепробовал
         0,            // флажки создания используются по умолчанию
         &dwThreadId); // возвращает идентификатор потока

        if (hThread == NULL)
          cout << "CreateThread failed.\n"; 
        else {
          cout << "CreateThread OK(" << hThread << ")\n"; 
          CloseHandle( hThread );
        }
      }
      return 1;
...
DWORD WINAPI ThreadFunc_Answer(LPVOID lpParam)
{
  LPCTSTR the_str = (LPCTSTR)lpParam;
  Sleep(5000);
  cout << "Answer:" << the_str << "\r\n";
  ExitThread(0);    // Специальный вызов для закрытия потока
}


Я извлекаю строку pcds->lpData из полученного сообщения и хочу передать эту строку в отдельный поток.
LPCTSTR на входе в поток меня вполне устроит.
По крайней мере внутри основного потока
(LPCTSTR)(pcds->lpData)
дает корректную строчку.

Дык вот. Мучаюсь и ничего кроме "Answer:" <абракодабра> ThreadFunc_Answer мне не выводит.

А вот код ниже вернет "Answer:STRING DIRECT" :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
        hThread = CreateThread(
         NULL,         // атрибуты безопасности по умолчанию
         0,            // размер стека используется по умолчанию
         ThreadFunc_Answer,   // функция потока
         "STRING DIRECT", // аргумент функции потока (void*)&(pcds->lpData)"STRING DIRECT"
         0,            // флажки создания используются по умолчанию
         &dwThreadId); // возвращает идентификатор потока



Но мне то нужно передать строку-параметр.
Делается ради того чтоб не держать вызывающее App, чтобы C++ сразу ответил на принятое SendMessage.

Тут подробности:
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?

Не, если ТУ задачу можно решить по-другому, то скажите как.

P.S. Я в лабиринте C-шных строк и указателей все равно не разберусь, это паталогия, мне просто надо сделать в конкретном случае.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407774
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77По крайней мере внутри основного потока
(LPCTSTR)(pcds->lpData)
дает корректную строчку.
А память по этому адресу живёт достаточно долго чтобы поток успел ею воспользоваться? Или
таки освобождается ещё задолго до этого?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407781
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Ну, память я думаю живет минимум до строчки
Код: plaintext
1.
return 1;


когда вызывающая
SendMessage (WM_COPYDATA)
получает свой код возврата.
Именно по этой причине WM_COPYDATA нельзя использовать с PostMessage

Моя задача как раз считать pcds->lpData, и отфутболить ответ в SendMessage (как только так сразу).
А потом уже что-то делать с String = < pcds->lpData > (думаю поток здесь кстати)

Ну, да. Скорее всего после return 1; память "пуста".
Вопрос как извернуться.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407793
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Вопрос как извернуться.
Разве не очевидно? Выделить новое место для хранения и скопировать содержимое туда. Вот
его-то и передавать потоку.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407798
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

И как это сделать?
Желательно без глобальной переменной (а вдруг несколько параллельных команд будет - хотя по задуманной логике вряд ли я это разрешу, потому как чтобы давать "следующую" команду, по логике надо знать ответ на "предыдущую", а этот ответ возвращается ф-цией потока).
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407806
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovРазве не очевидно?
Мне не очевидно.
В VB6 я бы извернулся так (как вариант, с потоками в VB6 глухо)

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Public the_str as String

    Case WM_COPYDATA
      If cds.dwData = 100 Then 'тест-запрос
        the_str = PtrToString_len(cds.lpData, cds.cbData)
        'и делай с этой the_str чего хочешь и где хочешь
        Timer1.enabled=true
        ' return ответ на SendMessage

'а в таймере 
   Debug.Print the_str
   Timer1.enabled=false

но смысл надеюсь понятен
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407902
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Мне не очевидно.
Значит тебе надо забыть бейсик и начать изучать работу самого компьютера и программ на нём.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407943
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovЗначит тебе надо забыть бейсик и начать изучать работу самого компьютера и программ на нём.
Dimitry, давай я как нибудь сам разберусь что мне надо забыть и что начать изучать.

Я пришел не с воплями "ПА-МА-ГИ-ТЕ ничего не знаю",
я пришел с кодом, четко указал место где не получается и попросил помочь конкретно с этим местом кода.
При этом честно предупредил, что "в лабиринте C-шных строк и указателей все равно не разберусь" и что "мне просто надо сделать в конкретном случае".

Нет проблем, я погуглил и нашел ответ :
Код: 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.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:
      cout << "WM_COPYDATA" << endl;
      COPYDATASTRUCT* pcds;
      pcds = (COPYDATASTRUCT*)lparam;
...
      } else if (pcds->dwData == 100) {//тест запрос

        DWORD dwThreadId;
        HANDLE hThread;

        char * the_str = new char[pcds->cbData];
        *the_str=0;
        strncat(the_str, (char *)(pcds->lpData), pcds->cbData);

        hThread = CreateThread(
         NULL,         // атрибуты безопасности по умолчанию
         0,            // размер стека используется по умолчанию
         ThreadFunc_Answer,   // функция потока
         (LPVOID)the_str, // аргумент функции потока
         0,            // флажки создания используются по умолчанию
         &dwThreadId); // возвращает идентификатор потока

        if (hThread == NULL)
          cout << "CreateThread failed.\n"; 
        else {
          cout << "CreateThread OK(" << hThread << ")\n"; 
          CloseHandle( hThread );
        }
      }
      return 1;

DWORD WINAPI ThreadFunc_Answer(LPVOID lpParam)
{
  //char * mystring = (char *)lpParam;
  const char* mystring = reinterpret_cast<const char*>(lpParam);
  //LPCTSTR the_str = (LPCTSTR)mystring;
  PString the_str = PString(mystring); //PString -тип строк оптимальный для данной C++ программы
  Sleep(5000);
  cout << "Answer:" << the_str << "@\r\n"; //@ чтоб проверить что не прицепили хвост мусора
  delete [] mystring;
  ExitThread(0);    // Специальный вызов для закрытия потока
}




Просто рассчитывал что здесь мне подскажут эти несколько строчек кода быстрее.
Что ж, спасибо, пришлось потратить несколько часов на поиск.
И я даже не спрашиваю, правильно ли я сделал.
Думаю с кодом все в порядке. Работает и иже с ним, вроде все хандлы и потоки закрыл и память очистил (delete [] mystring).
Потому что у вас сейчас начнется академическая дискуссия на неделю вперед с миллионом вариантов.

От того что я этот код нарыл и подогнал под себя, ясности в понимании char[], char *, const char* reinterpret_cast и т.п. больше не стало.
Для себя считаю более разумным и эффективным потратить время на изучение .Net (чем сейчас параллельно занимаюсь), а не на копание в указателях и пропасти сишных строк.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407944
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя нет, один вопрос остался.

Код: 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.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:

...

        HWND hwndTarget = (HWND)wparam; //wparam = HWND

        hThread = CreateThread(
         NULL,         // атрибуты безопасности по умолчанию
         0,            // размер стека используется по умолчанию
         ThreadFunc_Answer,   // функция потока
         (LPVOID)the_str, // аргумент функции потока
         0,            // флажки создания используются по умолчанию
         &dwThreadId); // возвращает идентификатор потока

DWORD WINAPI ThreadFunc_Answer(LPVOID lpParam)
{
  //char * mystring = (char *)lpParam;
  const char* mystring = reinterpret_cast<const char*>(lpParam);
  //LPCTSTR the_str = (LPCTSTR)mystring;
  PString the_str = PString(mystring); //PString -тип строк оптимальный для данной C++ программы
  Sleep(5000);

...
   HWND hwndTarget = ??????????????; //надо как-то передать hwndTarget в ф-цию потока
   SendMessage(hwndTarget, ...);
 

  delete [] mystring;
  ExitThread(0);    // Специальный вызов для закрытия потока
}



Т.е. мне в реальном коде надо кроме сообщения (строка) передать в ф-цию потока еще и hwndTarget (hwnd окна пославшего сообщение).
Стало быть передать структуру через аргумент функции потока.
Как это сделать?
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407953
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так нормально?
Я передаю в ф-цию потока структуру ForSend,
которая в свою очередь содержит строку msg, размер которой я задаю динамически (new char[pcds->cbData];) -мог бы написать char msg[1024], но чего память зря транжирить.

Код работает как мне надо:
1) сразу возвращает ответ на SendMessage (чтоб вызывающее приложение не висело 5 секунд)
2) корректно передает строку-команду и hwnd вызывающего приложения в поток
3) через 5 сек шлет ответ вызывающему приложению (hwnd) из потока.

Интересует в основном ответ на 2 вопроса:
1. Правильно ли я освобождаю память которую я захапал, чтоб передать параметры в поток (то что я выделил в полном коде)?
Код: plaintext
1.
2.
  delete [] in->msg; //освобождаю память под строку
  delete in; //освобождаю память под структуру

2. Правильно ли я грохаю поток.
1) CloseHandle( hThread ); - я делаю сразу, он мне нафик не нужен
2) ExitThread(0); -я делаю в конце ф-ции потока, когда она сделала что мне надо и более не нужна


Код: 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.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
struct ForSend{
   HWND hwnd;
   char * msg;
};

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:
      COPYDATASTRUCT* pcds;
      pcds = (COPYDATASTRUCT*)lparam;
...
      } else if (pcds->dwData == 100) {//тест запрос

        DWORD dwThreadId;
        HANDLE hThread;

        char * the_str = new char[pcds->cbData];
        *the_str=0;
        strncat(the_str, (char *)(pcds->lpData), pcds->cbData);

        ForSend *SendPr = new ForSend;
        SendPr->hwnd = (HWND)wparam;
        SendPr->msg = the_str;

        hThread = CreateThread(
         NULL,         // атрибуты безопасности по умолчанию
         0,            // размер стека используется по умолчанию
         ThreadFunc_Answer,   // функция потока
         (LPVOID)SendPr, // аргумент функции потока
         0,            // флажки создания используются по умолчанию
         &dwThreadId); // возвращает идентификатор потока

        if (hThread == NULL)
          cout << "CreateThread failed.\n"; 
        else {
          cout << "CreateThread OK(" << hThread << ")\n"; 
          CloseHandle( hThread );
        }
      }
      return 1;
...
DWORD WINAPI ThreadFunc_Answer(LPVOID lpParam)
{
  //ForSend * in = (ForSend *)lpParam;
  const ForSend* in = reinterpret_cast<const ForSend*>(lpParam);
  PString the_str = PString(in->msg);
  Sleep(5000);
  cout << "Answer:" << the_str << "@\r\n";
  cout << "Hwnd:" << in->hwnd << "\r\n";

  HWND hwndTarget = in->hwnd;
  std::string buffer;
  stringstream to_buffer;
  to_buffer << "Answer:" << the_str << "\r\n";
  buffer = to_buffer.str();
  to_buffer.str("");

  COPYDATASTRUCT cds;
  cds.dwData=101; //тест ответ на запрос
  cds.cbData = static_cast<DWORD>(buffer.length()) + 1;
  cds.lpData = const_cast<char *>((buffer.c_str()));
  SendMessage(hwndTarget, WM_COPYDATA, 0, (LPARAM) &cds);

  delete [] in->msg; //освобождаю память под строку
  delete in; //освобождаю память под структуру
  ExitThread(0);    // Специальный вызов для закрытия потока
}
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407983
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 2. Правильно ли я грохаю поток.
1) CloseHandle( hThread ); - я делаю сразу, он мне нафик не нужен
2) ExitThread(0); -я делаю в конце ф-ции потока, когда она сделала что мне надо и более не нужна
Читай Джеффри Рихтер "Windows для профессионалов. Создание эффективных Win32-пpилoжeний с учетом специфики 64-разрядной версии Windows", там про потоки очень подробно.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38407998
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_SlaЧитай...
Слушай, я вот другую книгу читаю:
Джефри Рихтер CLR via C#
Ничего?

А ты не можешь проще ответить?
1) Да, делаешь правильно.
или
2) Нет, не правильно.
Допиши строки такие-то, убери строку такую то.
или
3) Я не знаю. Я сам еще не дочитал эту книгу. (в этом случае можно ничего не отвечать)

Только не обижайся. Но я все-таки не спрашивал что мне прочесть.
И я даже не спрашиваю как написать код, я его уже написал, и он рабочий.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408281
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77...можешь проще ответить?...я его уже написал, и он рабочий.

Вам дали правильный и самый толковый ответ. Лучше первоисточник, чем трансляция. Тем более речь не о мысли, а о чисто технических аспектах. Это, что касаемо Рихтера. В частности то, что заюзали Вы - мягко говоря глюкало. У Рихтера разжовано что, как и почему. В добавок это не список статей "аля МСДН", а структурированная и понятно изложенная информация.

Что касаемо кода.
Он то рабочий (до некоторой степени), но как это сказать - "автогеном через одно место гланды удалять".
Ну и по жизни, будете для себя переоткрывать америку несколько раз по данной теме.

Обычно делается следующее:

делаете класс.
при старте потока передаёте this этого класса. Внутри потока приводите указатель на класс и юзаете все его методы и свойства.

Так оно просче, понятней и не провалитесь в последствии тонкого льда в дальнейшем.

удачи Вам
(круглый)
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408282
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Код: plaintext
1.
DWORD WINAPI ThreadFunc_Answer(LPVOID lpParam)



Все параметры потоку передаются через параметр lparam. Туда можно запихать либо любое значение базовых типов, либо указатель на любой тип данных.
При этом вызывающий код преобразует указатель или значение типа в LPARAM, а вызываемый (код потоковой функции) делает обратное преобразование, и оно должно быть именно таким, какое было на входе.

Как тебе уже правильно заметил твой тёска, память, на которую ссылаются, должна быть доступна достаточно долгое время, чтобы
дочерний поток смог её прочитать. Поэтому что-то типа ссылки на локальную переменную не годится -- вызов потоковой функции асинхронный, сначала вызывается CreateThread, потом код вызывающего потока продолжается, затем через какое-то время начинается дочерний поток и вызывается его функция.

Достаточно хороший подход -- выделить память под данные в вызывающем коде род. потока и передать ссылку на неё дочернему, а в дочернем скопировать данные в локальные переменные и память удалить.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408286
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Dimitry Sibiryakov,

Ну, память я думаю живет минимум до строчки
Код: plaintext
1.
return 1;




Этого мало .
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408294
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,


Код: plaintext
1.
2.
  
 HWND hwndTarget = ??????????????; //надо как-то передать hwndTarget в ф-цию потока



Если надо передавать несколько параметров, подход такой:

объявляешь структуру, содержащую все нужные параметры.

создаёшь экземпляр структуры динамически, заполняешь её нужными значениями, указатель передаёшь в CreateThread.

на входе в ThreadFunc преобразуешь lPARAM в указатель на структуру, распаковываешь параметры, структуру удаляешь.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408299
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Код: plaintext
1.
  (LPVOID)SendPr, // аргумент функции потока



Надо передавать АДРЕС, а не саму структуру по значению.

Код: plaintext
1.
  (LPVOID)(void*) &SendPr, // аргумент функции потока
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408309
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Код: 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.
DWORD WINAPI ThreadFunc_Answer(LPVOID lpParam)
{
  //ForSend * in = (ForSend *)lpParam;
  ForSend* in = reinterpret_cast<ForSend*>(lpParam);  // НЕ ДОЛЖНО БЫТЬ const !
  PString the_str = PString(in->msg);
  Sleep(5000);
  cout << "Answer:" << the_str << "@\r\n";
  cout << "Hwnd:" << in->hwnd << "\r\n";

  HWND hwndTarget = in->hwnd;
  std::string buffer;
  stringstream to_buffer;
  to_buffer << "Answer:" << the_str << "\r\n";
  buffer = to_buffer.str();
  to_buffer.str("");

  COPYDATASTRUCT cds;
  cds.dwData=101; //тест ответ на запрос
  cds.cbData = static_cast<DWORD>(buffer.length()) + 1;
  cds.lpData = const_cast<char *>((buffer.c_str()));
  SendMessage(hwndTarget, WM_COPYDATA, 0, (LPARAM) &cds);

  // Правильно. 
  delete [] in->msg; //освобождаю память под строку
  delete in; //освобождаю память под структуру

  // Однако 

  // блин, да просто вместо этого
  //ExitThread(0);    // Специальный вызов для закрытия потока
  return 0;
}



Однако внутри ForSend можно хранить строку по значению, например, тот же std::string, тогда не надо будет дополнительно ещё выделять динамически память под значение строки (правда, это всё равно сделает сам std::string ).
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408327
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

авторИнтересует в основном ответ на 2 вопроса:
1. Правильно ли я освобождаю память которую я захапал, чтоб передать параметры в поток (то что я выделил в полном коде)?

delete [] in->msg; //освобождаю память под строку
delete in; //освобождаю память под структуру


Правильно. Только при выделени лучше strcpy/strncpy а не strcat -- нелепо как-то.

автор2. Правильно ли я грохаю поток.
1) CloseHandle( hThread ); - я делаю сразу, он мне нафик не нужен


Не очень. Как правило, родительский поток (главный) не может завершиться прежде, чем все дочерние завершатся.
Иначе приложение закроется, а дочерние потоки будут убиты. Если они ещё работали, их работа останется недолеланной.
Как правило (в 99% слочаев) в приложениях сохраняют все хендлы дочерних потоков и на выходе из приложения дожидаются их окончания с помощью WaitForXXXX.

автор2) ExitThread(0); -я делаю в конце ф-ции потока, когда она сделала что мне надо и более не нужна

Это вообще не нужно. Просто return.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408475
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivКак правило, родительский поток (главный) не может завершиться прежде, чем
все дочерние завершатся.
Значит Рихтер врёт, когда говорит, что нет такой вещи как "главный поток"?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408495
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

Спасибо огромное за комментарии.

Вот смотри, я поменял:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
//strcat -- нелепо как-то -ну да, но здесь думаю без разницы т.к. pcds->cbData обрабатывается только в потоке
        //strncat(the_str, (char *)(pcds->lpData), pcds->cbData); 
        strncpy(the_str, (char *)(pcds->lpData), pcds->cbData); 

//в ф-ции потока

//ладно сделал, все одно в reinterpret_cast ничего не понимаю, делал по аналогии с const char *
  //const ForSend* in = reinterpret_cast<const ForSend*>(lpParam); 
  ForSend* in = reinterpret_cast<ForSend*>(lpParam);  

//полагаю в данном случае это все равно что написать "Exit Sub перед End Sub", вынужден согласиться
  //ExitThread(0);    // Специальный вызов для закрытия потока
  return 0;



MasterZivавтор2. Правильно ли я грохаю поток.
1) CloseHandle( hThread ); - я делаю сразу, он мне нафик не нужен


Не очень. Как правило, родительский поток (главный) не может завершиться прежде, чем все дочерние завершатся.
Иначе приложение закроется, а дочерние потоки будут убиты. Если они ещё работали, их работа останется недолеланной.
Как правило (в 99% слочаев) в приложениях сохраняют все хендлы дочерних потоков и на выходе из приложения дожидаются их окончания с помощью WaitForXXXX.

Понимаешь в чем фишка.
Я вызываю поток из обработчика SendMessage(WM_COPYDATA) ДРУГОГО приложения.
И если я воткну WaitForSingle... (да, читал я об этом)
то ДРУГОЕ тоже будет ждать WaitFor,
я бы мог _Answer сделать без всяких Thread,
но именно чтоб ДРУГОЕ не ждало я и сделал поток.
А CloseHandle мне сделать предписано по-любому, и самое простое это сделать сразу, благо это не приводит к принудительному завершению потока.
В реальном приложении
не Sleep(5000);
а функция инициализации телефонного вызова (например по SIP)
которая должна вернуть "Уникальный идентификатов" вызова,
и этот идентификатор я отправляю назад в ДРУГОЕ приложение,
но вызов может устанавливаться не 2 мс, а напр. 3 сек (если не локалка),
и я не хочу чтобы ДРУГОЕ приложение висело все это время.
>Иначе приложение закроется, а дочерние потоки будут убиты. Если они ещё работали, их работа останется недолеланной.
Если приложение закроется в момент инициализации вызова, то начавшийся было телефонный вызов также будет убит,
и возврат "Уникального идентификатора" этого вызова мне скорее вреден, отслеживание вызова начинается только после возрата идентификатора. Т.е. я ничем не рискую.
С учетом этого комментария надеюсь корректно?

А теперь о грустном:
Вот как ты сказал
MasterZivДмитрий77,

Код: plaintext
1.
  (LPVOID)SendPr, // аргумент функции потока



Надо передавать АДРЕС, а не саму структуру по значению.

Код: plaintext
1.
  (LPVOID)(void*) &SendPr, // аргумент функции потока


выдает абракодабру,
а при замене strncat на strncpy еще и дает краш приложения.

Посмотри, но мне кажется что мой код как раз передает указатель на структуру (звездочка стоит при определении),
ForSend *SendPr = new ForSend;
Неправ?
Но мой то вариант как раз работает.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408682
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovMasterZivКак правило, родительский поток (главный) не может завершиться прежде, чем
все дочерние завершатся.
Значит Рихтер врёт, когда говорит, что нет такой вещи как "главный поток"?..


Нет, не врет. Потому что он так не говорит.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408697
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77
Посмотри, но мне кажется что мой код как раз передает указатель на структуру (звездочка стоит при определении),
ForSend *SendPr = new ForSend;
Неправ?
Но мой то вариант как раз работает.


Ой, это я напутал, ты прав. Указатель у тебя передается.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408705
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivон так не говорит.
Он говорит, что все потоки равноправны и процесс завершается когда завершается последний
из них.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408888
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovMasterZivон так не говорит.
Он говорит, что все потоки равноправны и процесс завершается когда завершается последний
из них.


http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx

MSDN
CreateProcess function

Creates a new process and its primary thread . The new process runs in the security context of the calling process.

...

The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached DLLs.
Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
...



Отсюда вывод: первый поток приложения, тот, который на выходе зовёт ExitProcess, и в котором вызывается функция main (или WinMain), можно называть главным потоком приложения.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408901
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivтот, который на выходе зовёт ExitProcess
Ну так это если этот первый среди равный ещё вызовет ExitProcess(), чего совершенно не
обязан делать...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38408983
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

А как ты думаешь, по выходу из main что происходит ?
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38409019
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivпо выходу из main что происходит ?
У стандартного кода инициализации МSVC - да, вызов ExitProcess. Но это чисто проблемы
данного инициализатора.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38409135
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дима, ты конечно все правильно говоришь, только есть одно "но": какой-то поток из многих потоков приложения должен завершить процесс. И обычно это делает тот поток, с которого процесс и начался, выполнением точки входа в приложение. По-моему все очень логично.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38409151
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivкакой-то поток из многих потоков приложения должен завершить процесс

Процесс и сам по себе завершится, когда в нём не останется ни одного потока.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38409381
_Прохожий_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivНе очень. Как правило, родительский поток (главный) не может завершиться прежде, чем все дочерние завершатся.
Иначе приложение закроется, а дочерние потоки будут убиты. Если они ещё работали, их работа останется недолеланной.
Как правило (в 99% слочаев) в приложениях сохраняют все хендлы дочерних потоков и на выходе из приложения дожидаются их окончания с помощью WaitForXXXX.

Закрытие или не закрытие хэндла потока, возвращенного CreateThread, не влияет на завершение процесса. Влияет только на уничтожение thread object, т.е. системной структуры, описывающей поток. Он не будет уничтожен после завершения потока пока ВСЕ референсы(т.е. не только хэндл, возвращенный CreateThread, а и дубликаты, если они были) на хэндл потока не будут закрыты CloseHandle. Иначе нельзя было бы получить например код завершения потока, после того как поток завершился.
Поэтому закрытие хэндла потока после его получения, просто дает системе возможность удалить thread object сразу же после завершения потока. И так делать не только можно, но и нужно, если хэндл потока не будет использоваться позже.
Ну а не закрытие хэндла потока соответственно вызывает утечку памяти.

Дмитрий77, я думаю вам еще нужно знать, что создание потока с помощью CreateThread на 100% безопасно только если не используется CRT и библиотеки, использующие CRT.
...
Рейтинг: 0 / 0
Как передать строковый параметр в CreateThread?
    #38410540
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Прохожий_Дмитрий77, я думаю вам еще нужно знать, что создание потока с помощью CreateThread на 100% безопасно только если не используется CRT и библиотеки, использующие CRT.
исходное С++ приложение (без моих наворотов) - чисто консольное и платформенно-независимое (т.е. годится и под линукс, и т.д.),
я туда добавил в частности CreateWindow - окно вида HWND_MESSAGE для ловли сообщений из вне
Не похоже что там будут проблемы из-за потоков.

А вот любые попытки использовать CreateThread в VB6 например (нарочно попытался воспроизвести в VB6 подобное) - это ДА - сплошные краши.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как передать строковый параметр в CreateThread?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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