Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.05.2010, 21:55   #1
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
Восклицание CreateThreads

Код:
HANDLE mutex;
mutex=CreateMutex(NULL,FALSE,NULL);
             DWORD result;
             result=WaitForSingleObject(mutex,INFINITE);
             if(result==WAIT_OBJECT_0){
                SEND=CreateThread(NULL,0,CLIENT_SEND,(void *)&client,0,&ID_SEND);
                
                RECV=CreateThread(NULL,0,CLIENT_RECV,(void *)&client,0,&ID_RECV);
                ReleaseMutex(mutex);
             }
Подскажите пожалуйста,почему при запуске приложения создается сразу четыре потока SEND(а нужно чтобы один SEND и RECV)
Единственный способ стать умнее - играть с более умным противником.
Sam Gold вне форума Ответить с цитированием
Старый 08.05.2010, 23:34   #2
liljon
Форумчанин
 
Регистрация: 03.01.2010
Сообщений: 229
По умолчанию

по чем знать без остального кода? приведенный код создает 2 потока и все.
подпись
liljon вне форума Ответить с цитированием
Старый 08.05.2010, 23:54   #3
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Функция принимающего потока:
Код:
DWORD  WINAPI CLIENT_SEND(LPVOID param){
      mutex=CreateMutex(NULL,FALSE,NULL);
       int ex=0;
       while(ex==0){
      
      DWORD result;
      result=WaitForSingleObject(mutex,0);
      if(result==WAIT_OBJECT_0){

         SOCKET client;
   	  	 
         client=*((SOCKET *)param);
         char target[100];
   	  
         cin.ignore(0);
                
         std::cout <<"Enter target of messageand and message:\n "<< std::endl;
                  
         cin.getline(target,100);
         
         send(client,target,100,0);
         	    
         
        ReleaseMutex(mutex);
        ex=CheckForExit(client); //======в зависимости от введенного символа продолжаем или выходим из цикла
     }
     CloseHandle(mutex);
  }
  ExitThread(0);
  return 0; 
 
     
}
функция принимающего потока:
Код:
DWORD  WINAPI CLIENT_RECV(LPVOID param){
 

   mutex_recv_th=CreateMutex(NULL,FALSE,NULL);
   DWORD result;
   result=WaitForSingleObject(mutex_recv_th,0);
   if(result==WAIT_OBJECT_0){

   	SOCKET client;
   	client=*((SOCKET *)param);
   
   	int ex=0;
   
   	while(ex==0){
   	       char  *buf_r;
   	       buf_r=(char *)malloc(100);
   	    
   	        char  *buf_nam;
   	        buf_nam=(char *)malloc(10);
        
      	        int nam=recv(client,buf_nam,10,0);
   	        int mes=recv(client,buf_r,100,0);
                     if(((nam)||(mes))>0){
   	                  std::cout<< "\n Upload new message  from "<<buf_nam<<" : " << buf_r <<std::endl;
   	 	      free(buf_r);
   	                   free(buf_nam);
   	         }
	 
	  
	  ReleaseMutex(mutex_recv_th);
	  }//=============while
	  
	  
   }//==========if(result==WAIT_OBJECT_0){
   CloseHandle(mutex_recv_th);   
   ExitThread(0);
   return 0;
}
Единственный способ стать умнее - играть с более умным противником.
Sam Gold вне форума Ответить с цитированием
Старый 09.05.2010, 00:16   #4
liljon
Форумчанин
 
Регистрация: 03.01.2010
Сообщений: 229
По умолчанию

код из функций потоков не нужен был. Просто где то в вашей программе вызваеться неоднократно CreateThread. Я хотел посмотреть на все.

Насчет потоков хочу сделать оговорочку. Когда вы передаете параметр в поток, указатель на него может быть разрушен еще до того как поток будет создан. Тоесть указатель lparam ничего содержать не будет

Код:
DWORD WINAPI Thread(LPVOID lparam)
{
 int r = *(int*)lparam;
 return 0;
}

void create()
{
 int s= 10;
 CreateThread(0,0,Thread,&s,0,0,0);
}

int main()
{
 create();
 while (1)Sleep(1);
}
По идеи переменная "r" в "Thread", должна содержать число 10, но на самом деле там ничего не будет, так как пока поток создавался, переменная s успела разрушиться, в тот момент когда функция create завершилась. Передавать в поток нужно либо глобальные переменные, либо поставить задержку после CreateThread.

Код:
DWORD WINAPI Thread(LPVOID lparam)
{
 int r = *(int*)lparam;
 return 0;
}

void create()
{
 int s= 10;
 HANDL th = CreateThread(0,0,Thread,&s,0,0,0);
 WaitForSingleThread(th,INFINITE);
}

int main()
{
 create();
 while (1)Sleep(1);
}
подпись
liljon вне форума Ответить с цитированием
Старый 09.05.2010, 11:12   #5
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Вот вся прога. Возможно множественный вызов потоков происходит из-за того, что они в цикле?

Код:
int main(){

   SOCKET client;
  WSADATA wsaData;
  WORD version;
  DWORD ID_RECV,ID_SEND;
  HANDLE RECV,SEND; 

   int error;
   HANDLE mutex1;
   
   
   
    if(check_for_error_win(wsaData,version,error)){
		
	char name[10];
   	
   	
   	std::cout << "Enter your name \n" << std::endl;

             cin.getline(name,10);
             int ex=0;
	while(ex==0){
    	
      

   		client = socket( AF_INET, SOCK_STREAM, 0 );
   
   		struct sockaddr_in sin;
   
   		memset( &sin, 0, sizeof(sin) );
   
   		sin.sin_family = AF_INET;
   
   		sin.sin_port = htons(7007);
   		sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   	
   
   
   		if ( connect( client, (struct sockaddr *)&sin, sizeof sin ) == SOCKET_ERROR ){
   		     std::cout<<"could not connect to server"<< std::endl;
         	                  getchar();
      
   		}
   
        
      	              std::cout << " connect to server "<<std::endl;
      	 
          
          

                           send(client,name,10,0);
                           PrintList(client);//Вывод списка online пользователей
             
                
   	  
   	  //======================================
   
      	  
      	 
                           mutex1=CreateMutex(NULL,FALSE,NULL);
                           DWORD result;
                           result=WaitForSingleObject(mutex1,INFINITE);
                           if(result==WAIT_OBJECT_0){
                               SEND=CreateThread(NULL,0,CLIENT_SEND,(void *)&client,0,&ID_SEND);
                
                              RECV=CreateThread(NULL,0,CLIENT_RECV,(void *)&client,0,&ID_RECV);
                              ReleaseMutex(mutex1);
                            }
             
    
             
              
              
            
            	 
            	 
               	 
         
            ex=CheckForExit(client);  //====в зависимости от введенного символа продолжаем или выходим из цикла=========
   		       
          }//======while====
             
           
           
   }
   	WSACleanup();
   
      return 0;
     
}
Единственный способ стать умнее - играть с более умным противником.
Sam Gold вне форума Ответить с цитированием
Старый 09.05.2010, 19:06   #6
liljon
Форумчанин
 
Регистрация: 03.01.2010
Сообщений: 229
По умолчанию

не возможно, а да. Осталось угадать где функция CheckForExit и проблема почти решилась. Я чорт возьми не телепат

В теле основной подпрограммы вам ненужен цикл while(ex==0), это если я правильно понял чего вы хотите сделать. Если правиьлно, то подключение и потоки создавайте не в теле цикла. А чтобы программа не завершилась, необходимо зациклить основной поток. После создания потоков напишите while (1) Sleep(1);
подпись

Последний раз редактировалось liljon; 09.05.2010 в 19:10.
liljon вне форума Ответить с цитированием
Старый 09.05.2010, 23:39   #7
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Цитата:
Сообщение от liljon Посмотреть сообщение

В теле основной подпрограммы вам ненужен цикл while(ex==0), это если я правильно понял чего вы хотите сделать.
Я пишу прогу для обмена сообщениями междку клиентами. Цикл while(ex==0) нужен для того, чтобы пользователь мог посылать и принимать сообщения, пока не захочет выйти из проги(за это отвеччает функция CheckForExit(SOCKET client) если ползователь ввел 'y' то ex=1=> выходим из цикла и завершаем прогу)
А если убрать while то можно отправить только 1 сообщение
Единственный способ стать умнее - играть с более умным противником.
Sam Gold вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц