Многопоточность и CreateThread
От: Аноним  
Дата: 11.11.08 10:56
Оценка:
Всем привет.

Народ вот с такой гадостью столкнулся. Смысл такой:

DWORD ThreadFun(void * arguments)
{
  cObject * s = (cObject *) arguments

  s->Method();

  while(SomeCondition) {
    ...
  }

  ExitThread(0);
  return 0;
}

int main()
{
  ...
  cObject object;
  cObject * o = & object;
  CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
  ...
}


Но весь ужас ситуации в том, что как только отрабатывает первая строчка внутри
s->Method();


Вызывается деструктор cObject и вылетает error, что std::bad_alloc in memory ... .
Что тут не так и как это убить ?
Re: Многопоточность и CreateThread
От: Аноним  
Дата: 11.11.08 11:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Всем привет.


А>Народ вот с такой гадостью столкнулся. Смысл такой:


А>
А>DWORD ThreadFun(void * arguments)
А>{
А>  cObject * s = (cObject *) arguments

  s->>Method();

А>  while(SomeCondition) {
А>    ...
А>  }

А>  ExitThread(0);
А>  return 0;
А>}

А>int main()
А>{
А>  ...
А>  cObject object;
А>  cObject * o = & object;
А>  CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
А>  ...
А>}
А>


А>Но весь ужас ситуации в том, что как только отрабатывает первая строчка внутри

А>
s->>Method();
А>


А>Вызывается деструктор cObject и вылетает error, что std::bad_alloc in memory ... .

А>Что тут не так и как это убить ?
Так поток выполняется одновременно с потоком в котором main работает. Если в том потоке удалить s до того как ThreadFun завершит исполнение, то — s удалится, было бы странно еслиб не удалялся Соответственно надо пересматривать логику удаления s.
ExitThread кстати не нужен.
Re: Многопоточность и CreateThread
От: Draqon  
Дата: 11.11.08 11:03
Оценка:
Дело в том, что вы создаёте объект на стеке. Создавайте с помощью new, и потом перед выходом из треда делаете delete.
Re: Многопоточность и CreateThread
От: spylogsster Россия  
Дата: 11.11.08 11:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Всем привет.


А>Народ вот с такой гадостью столкнулся. Смысл такой:


А>
А>DWORD ThreadFun(void * arguments)
А>{
А>  cObject * s = (cObject *) arguments

  s->>Method();

А>  while(SomeCondition) {
А>    ...
А>  }

А>  ExitThread(0);
А>  return 0;
А>}

А>int main()
А>{
А>  ...
А>  cObject object;
А>  cObject * o = & object;
А>  CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
А>  ...
А>}
А>


А>Но весь ужас ситуации в том, что как только отрабатывает первая строчка внутри

А>
s->>Method();
А>


А>Вызывается деструктор cObject и вылетает error, что std::bad_alloc in memory ... .

А>Что тут не так и как это убить ?

выполнение функции после
А> CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);

продолжается и объект object уничтожается по выходе из функции main, либо создай его ручками через new, либо копируй объект и передавай в поток копию, а еще лучше применить нормальный механизм межпоточного взаимодействия, в зависимости от контекста задачи
Re: Многопоточность и CreateThread
От: Bell Россия  
Дата: 11.11.08 11:05
Оценка:
Здравствуйте, Аноним, Вы писали:


А>  ...
А>  cObject object;
А>  cObject * o = & object;
А>  CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
А>  ...


Ты передаешь в поток указатель на локальный объект, который разрушается к тому времени, когда поток пытается осуществить доступ к нему.
Лечить, например, так:
cObject * o = new cObject();
CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);


Само собой нужно не забыть удалить объект в функции ThreadFun.
Любите книгу — источник знаний (с) М.Горький
Re[2]: Многопоточность и CreateThread
От: Аноним  
Дата: 11.11.08 11:13
Оценка:
Во спасибо народ))

Только у меня такой еще вопросик родился.
Допустим, что нажав Кнопку1 я создал тот поток и он с бесконечным циклом.
Но вот он мне надоел и я захотел его убить. Какой функцией это сделать если его HANDLE сохранен
Говорили, что TerminateThread лучше не юзать, но вроде бы он для этого и создан.
Или же нет??
Re[3]: Многопоточность и CreateThread
От: Draqon  
Дата: 11.11.08 11:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Во спасибо народ))


А>Только у меня такой еще вопросик родился.

А>Допустим, что нажав Кнопку1 я создал тот поток и он с бесконечным циклом.
А>Но вот он мне надоел и я захотел его убить. Какой функцией это сделать если его HANDLE сохранен
А>Говорили, что TerminateThread лучше не юзать, но вроде бы он для этого и создан.
А>Или же нет??

Единственный способ корректно завершить тред — это выйти из его ThreadFunc обычным return'ом. Так что лучше всего ваш бесконечный цикл превратить в
while (WaitForSingleObject(StopEvent, 0) == WAIT_TIMEOUT)
{
 .....
}
return 0; // <- когда снаружи сделают SetEvent, цикл прервется и здесь будет корректный выход из треда.

а снаружи делать SetEvent(StopEvent).
Re: Нужно больше информации
От: alzt  
Дата: 11.11.08 11:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но весь ужас ситуации в том, что как только отрабатывает первая строчка внутри

А>
s->>Method();
А>


А>Вызывается деструктор cObject и вылетает error, что std::bad_alloc in memory ... .

А>Что тут не так и как это убить ?

Чтобы не гадать — в таком коде

int main()
{
...
cObject object;
cObject * o = & object;
CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
Sleep(100000);
...
}
[/ccode]

тоже деструктор сразу вызывается?
Re[2]: Нужно больше информации
От: spylogsster Россия  
Дата: 11.11.08 11:44
Оценка:
Здравствуйте, alzt, Вы писали:

A>Здравствуйте, Аноним, Вы писали:


А>>Но весь ужас ситуации в том, что как только отрабатывает первая строчка внутри

А>>
s->>>Method();
А>>


А>>Вызывается деструктор cObject и вылетает error, что std::bad_alloc in memory ... .

А>>Что тут не так и как это убить ?

A>Чтобы не гадать — в таком коде


A>int main()

A>{
A> ...
A> cObject object;
A> cObject * o = & object;
A> CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
A> Sleep(100000);
A> ...
A>}
A>[/ccode]

A>тоже деструктор сразу вызывается?

в данном случае он вызывается при выходе из функции main
[ccode]
{
...
cObject object;
...
// возврат из функции и вызов деструктора
}
/ccode]
Re: Многопоточность и CreateThread
От: R.O. Prokopiev Россия http://127.0.0.1/
Дата: 11.11.08 11:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>DWORD ThreadFun(void * arguments)
А>


Кроме вышеперечисленных бросается в глаза еще один баг:
ThreadFun должна быть определена с модификатором WINAPI,
иначе будут проблемы со стеком.

Вообще, для совместимости с рантайм-библиотеками, лучше использовать
_beginthread или _beginthreadex (и колбэк там как раз в стиле cdecl)
Re[2]: Многопоточность и CreateThread
От: Аноним  
Дата: 11.11.08 12:24
Оценка:
Ситуация чуть изменилась
теперь один поток создается и работает нормально, но вот второй уже вызывает ошибку, причем на этот раз просто говорит, что ошибка по адресы без всяких комментов. Причем эта ошибка происходит из-за того самого деструктора, только теперь уже на 2й объект... Если так пойдет, то гдето на 100 потоке я убью себя, а скорее и раньше

>Вообще, для совместимости с рантайм-библиотеками, лучше использовать

>_beginthread или _beginthreadex (и колбэк там как раз в стиле cdecl)

Врядли получится, т к libcmt пришлось отключить — конфликт с подлюченными сторонними.

Насчет евента понял — поковыряю — главное знать, что ковырять))
Вот сразу вопрос родился гляда на WAIT_TIMEOUT — должен быть задан или же может быть unlim?
Re[3]: Многопоточность и CreateThread
От: Draqon  
Дата: 11.11.08 12:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ситуация чуть изменилась

А>теперь один поток создается и работает нормально, но вот второй уже вызывает ошибку, причем на этот раз просто говорит, что ошибка по адресы без всяких комментов. Причем эта ошибка происходит из-за того самого деструктора, только теперь уже на 2й объект... Если так пойдет, то гдето на 100 потоке я убью себя, а скорее и раньше

>>Вообще, для совместимости с рантайм-библиотеками, лучше использовать

>>_beginthread или _beginthreadex (и колбэк там как раз в стиле cdecl)

А>Врядли получится, т к libcmt пришлось отключить — конфликт с подлюченными сторонними.


А>Насчет евента понял — поковыряю — главное знать, что ковырять))

А>Вот сразу вопрос родился гляда на WAIT_TIMEOUT — должен быть задан или же может быть unlim?

Почитай в msdn про WaitForSingleObject. И, скажем, у Рихтера — про многопоточное программирование под виндой.
Re[3]: Нужно больше информации
От: alzt  
Дата: 11.11.08 13:11
Оценка:
Здравствуйте, spylogsster, Вы писали:

A>>Чтобы не гадать — в таком коде


A>>int main()

A>>{
A>> ...
A>> cObject object;
A>> cObject * o = & object;
A>> CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
A>> Sleep(100000);
A>> ...
A>>}
A>>[/ccode]

А это ты создал ветку?
В первоначальном сообщении стоит многоточие, поэтому решил сразу уточнить — есть ли там какой-либо вид синхронизации или нет.
Re: Многопоточность и CreateThread
От: MShura  
Дата: 11.11.08 14:55
Оценка:
А>Что тут не так и как это убить ?

Если функция main закончится раньше чем ThreadFun, то позовется ExitProcess, который завершит все второстепенные потоки.
Если время жизни 'object' больше чем ThreadFun, то можно смело передавать его адрес в поточную функцию.
Re: Многопоточность и CreateThread
От: g_i  
Дата: 11.11.08 15:23
Оценка:
Здравствуйте, Аноним, Вы писали:

int main()
{
...
cObject object;
cObject * o = & object;
CreateThread(..., (LPTHREAD_START_ROUTINE) ThreadFun, s, ...);
...
WaitForSingleObject(threadHandle, INFINITE);
}
[/ccode]
Re[2]: Многопоточность и CreateThread
От: Sergey Chadov Россия  
Дата: 11.11.08 17:11
Оценка:
Здравствуйте, R.O. Prokopiev, Вы писали:


ROP>Вообще, для совместимости с рантайм-библиотеками, лучше использовать

ROP>_beginthread или _beginthreadex (и колбэк там как раз в стиле cdecl)

у _beginthreadex __stdcall
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.