На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Корректное завершение программы с рабочими потоками. , Завершить все сетевые операции до закрытии главного окна программы.
      Вот неправильный пример:

      Функции обработчиков сообщения закрытия главного окна:
      ExpandedWrap disabled
        void Cstl_network_ip_4_ip_6_udp_engineDlg::OnClose()
        {
            // TODO: добавьте свой код обработчика сообщений или вызов стандартного
         
            OnBnClickedButtonClose();
        }
         
        void Cstl_network_ip_4_ip_6_udp_engineDlg::OnBnClickedButtonClose()
        {
            // TODO: добавьте свой код обработчика уведомлений
         
            set_command_threads_stop(true);
         
            {
                void *local_stop_thread_parameters_structure = new thread_stop_parameters_structure_type;
         
                ((thread_stop_parameters_structure_type*)local_stop_thread_parameters_structure)->parameter_main_dialog = this;
         
                CWinThread *local_thread = AfxBeginThread(stop_waiting_thread,local_stop_thread_parameters_structure);
            }
        }


      Поток закрытия главного окна:
      ExpandedWrap disabled
        //  stop
         
        UINT __cdecl stop_waiting_thread(LPVOID parameter)
        {
            thread_stop_parameters_structure_type *local_stop_thread_parameters_structure = (thread_stop_parameters_structure_type *)parameter;
         
            if(local_stop_thread_parameters_structure==NULL)
            {
                return 0;
            }
         
            Cstl_network_ip_4_ip_6_udp_engineDlg *local_main_dialog = (local_stop_thread_parameters_structure)->parameter_main_dialog;
         
            if(local_main_dialog==NULL)
            {
                delete local_stop_thread_parameters_structure;
                return 0;
            }
         
         
         
         
         
            ApplicationManager am;
            //NetworkManager nm;
         
            try
            {
         
                IGDDiscoverProcess discoverer( 500000 );
         
                tg_redirect_delete.create_thread( boost::ref( discoverer ) );
                tg_redirect_delete.join_all();
         
                IGDDiscoverProcess::IGDControlInformations cinfos =
                    discoverer.GetAllIGDControlInformations();
                boost_foreach( IGDDiscoverProcess::ControlInfo info, cinfos )
                {
                    if( info.has_problem )
                    {
                        continue;
                    }
         
                    if( info.service_type == UPNPSERVICE_LAYER3FORWARDING1 )
                    {
                    }
                    else if( info.service_type == UPNPSERVICE_WANIPCONNECTION1)
                    {
                        UPNPNATHTTPClient soap( info.ip, info.port );
         
                        UPNPNATHTTPClient::SoapResult soap_res;
                        soap_res = soap.DeletePortMapping(
                            local_main_dialog->redirected_port_number, std::string("UDP"),
                            info.control_url, info.service_type
                            );
                        if( UPNPNATHTTPClient::SoapSucceeded == soap_res )
                        {
                            CString local_message("portmapping succeeded.");
                        }
         
                        soap_res = soap.DeletePortMapping(
                            local_main_dialog->redirected_port_number, std::string("TCP"),
                            info.control_url, info.service_type
                            );
                        if( UPNPNATHTTPClient::SoapSucceeded == soap_res )
                        {
                            CString local_message("portmapping succeeded.");
                        }
                    }
                    else if( info.service_type == UPNPSERVICE_WANCOMMONINTERFACECONFIG1 )
                    {
                    }
                    else if(info.service_type == UPNPSERVICE_WANPPPCONNECTION1)
                    {
                        UPNPNATHTTPClient soap( info.ip, info.port );
         
                        UPNPNATHTTPClient::SoapResult soap_res;
                        soap_res = soap.DeletePortMapping(
                            local_main_dialog->redirected_port_number, std::string("UDP"),
                            info.control_url, info.service_type
                            );
                        if( UPNPNATHTTPClient::SoapSucceeded == soap_res )
                        {
                            CString local_message("portmapping succeeded.");
                        }
         
                        soap_res = soap.DeletePortMapping(
                            local_main_dialog->redirected_port_number, std::string("TCP"),
                            info.control_url, info.service_type
                            );
                        if( UPNPNATHTTPClient::SoapSucceeded == soap_res )
                        {
                            CString local_message("portmapping succeeded.");
                        }
                    }
                }
         
            }
            catch( IGDDiscoverProcess::exception &e )
            {
                CString error(e.what());
            }
         
            Sleep(2000);
         
            {
                delete local_stop_thread_parameters_structure;
         
                WSACleanup();
         
                local_main_dialog->EndDialog(IDOK);
         
                return 1;
            }
        }


      Это в рабочих потоках работы с сетью во всех циклах:
      ExpandedWrap disabled
                if(local_main_dialog->get_command_threads_stop())
                {
                    break;
                }
                else
                {
                    Sleep(1);
                }
            }
         
            {
                delete local_listen_thread_parameters_structure;
                return 1;
            }
        }


      Конкретно не устраивает этот код (тут ошибка):
      ExpandedWrap disabled
            Sleep(2000);
         
            {
                delete local_stop_thread_parameters_structure;
         
                WSACleanup();
         
                local_main_dialog->EndDialog(IDOK);
         
                return 1;
            }
        }


      Вместо
      ExpandedWrap disabled
            Sleep(2000);

      Нужна какая-то синхронизация потоков (ожидание завершения всех потоков, количество которых заранее не известно).

      Какие есть варианты и идеи?
        Только что придумал вот что:
        Помещать CWinThread * после выполнения AfxBeginThread в список и ждать его как события после получения сообщения о требовании закрытия программы.

        ExpandedWrap disabled
          CWinThread *local_thread = AfxBeginThread(datagram_listen_connection_thread,local_listen_thread_parameters_structure);


        ExpandedWrap disabled
          DWORD local_result = WaitForSingleObject(local_thread->m_hThread,INFINITE);


        Будет ли так работать?

        Добавлено Сегодня

        Вот правильный рабочий код:

        ExpandedWrap disabled
          void Cstl_network_ip_4_ip_6_udp_engineDlg::OnBnClickedButtonClose()
          {
              // TODO: добавьте свой код обработчика уведомлений
           
              set_command_threads_video_stop(true);
              set_command_threads_web_camera_video_stop(true);
              set_command_threads_stop(true);
           
              {
                  void *local_stop_thread_parameters_structure = new thread_stop_parameters_structure_type;
           
                  ((thread_stop_parameters_structure_type*)local_stop_thread_parameters_structure)->parameter_main_dialog = this;
           
                  CWinThread *local_thread = AfxBeginThread(stop_waiting_thread,local_stop_thread_parameters_structure);
           
          //      threads_list.push_back(local_thread);
              }
          }


        ExpandedWrap disabled
              {
                  for
                      (
                      std::list<CWinThread *>::iterator local_threads_iterator=local_main_dialog->threads_list.begin();
                      local_threads_iterator!=local_main_dialog->threads_list.end();
                      local_threads_iterator++
                      )
                  {      
                      CWinThread *local_thread = *local_threads_iterator;
                      DWORD local_result = WaitForSingleObject(local_thread->m_hThread,INFINITE);
                  }
              }
           
              {
                  delete local_stop_thread_parameters_structure;
           
                  WSACleanup();
           
                  local_main_dialog->EndDialog(IDOK);
           
                  return 1;
              }
          }


        ExpandedWrap disabled
              {
                  void *local_listen_thread_parameters_structure = new thread_listen_parameters_structure_type;
           
                  ((thread_listen_parameters_structure_type*)local_listen_thread_parameters_structure)->parameter_main_dialog = this;
           
                  CWinThread *local_thread = AfxBeginThread(datagram_listen_connection_thread,local_listen_thread_parameters_structure);
           
                  threads_list.push_back(local_thread);
              }


        ExpandedWrap disabled
              char local_message_to_receive[CONST_MESSAGE_LENGTH_IMAGE_EVERY_TIME];
           
              LONG64 local_receive_counter = 0;
           
              for(;;)
              {
                  ZeroMemory(local_message_to_receive,CONST_MESSAGE_LENGTH_IMAGE_EVERY_TIME);
           
                  int local_bytes_received = 0;
           
                  network::ip_6::CSockAddr_ip_6 local_socket_address_peer;
           
           
           
           
           
           
                  if(local_main_dialog->get_command_threads_stop())
                  {
                      break;
                  }
                  else
                  {
                      Sleep(1);
                  }
              }
           
              {
                  delete local_listen_thread_parameters_structure;
                  return 1;
              }
          }


        Всем спасибо за внимание.

        Особенно тем, кто помог.
        Сообщение отредактировано: Kozlov_Sergey -
          M
          Не забываем про использование функции "Вопрос решён!"
          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0276 ]   [ 15 queries used ]   [ Generated: 15.05.24, 00:57 GMT ]