Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    MFC & threads: WaitForSingleObject s'addormenta e solo AfxMessageBox lo sveglia

    Sto scrivendo un programma con VC++ 6.0 e mi stanno succedendo cose strane coi thread.
    Il codice semplificato al massimo, quindi tralasciando le cose ovvie, è questo e riguarda la classe della finestra di dialogo, nella quale un pulsante deve avviare o terminare un thread.

    codice:
    class CMyDlg : public CDialog
    {
    ...
    	CWinThread* c;
    	int p;
    }
    
    ...
    
    UINT MyControllingFunction( LPVOID pParam )
    {
    	CMyDlg *v=(CMyDlg*)pParam;
    	while(1)
    	{
    		if (v->p==0) break;
    	}
    	return 0;
    }
    
    ...
    
    CMyDlg::CMyDlg()
    {
    	p=0;
    }
    
    CMyDlg::OnButton1()
    {
    	if (p==0)
    	{
    		p=1;
    		c=AfxBeginThread(MyControllingFunction,this,0,0, CREATE_SUSPENDED, NULL);
    		c->m_bAutoDelete=FALSE;
    		c->ResumeThread();
    		return;
    	}
    	
    	if(p==1)
    	{
    		p=0;
    		//AfxMessageBox("1");
    		WaitForSingleObject(c->m_hThread,INFINITE);
    		delete c;
    	}
    }
    Ebbene, cliccando il pulsante il thread viene creato e messo in esecuzione, cliccandolo un'altra volta la funzione WaitForSingleObject si blocca e non si schioda.
    Se però tolgo il commento e lascio quell'AfxMessageBox tutto funziona.
    Non è un problema di attesa, perché anche se al posto del messagebox ci metto uno Sleep non funziona lo stesso.
    Inoltre, nel momento in cui la funzione WaitForSingleObject viene chiamata il thread effettivamente si ferma, ma la funzione non ritorna.
    Anche inserendo un AfxEndThread(0) nella funzione del thread non cambia nulla.
    Un altro modo per farla funzionare è modificare il codice così:
    codice:
    class CMyDlg : public CDialog
    {
    ...
    	CWinThread* c;
    	int p;
    }
    
    ...
    
    UINT MyControllingFunction( LPVOID pParam )
    {
    	CMyDlg *v=(CMyDlg*)pParam;
    	while(1)
    	{
    		if (v->p==0) break;
    	}
    	return 0;
    }
    
    ...
    
    CMyDlg::CMyDlg()
    {
    	p=0;
    }
    
    CMyDlg::OnButton1()
    {
    	if (p==0)
    	{
    		p=1;
    		c=AfxBeginThread(MyControllingFunction,this,0,0, 0, NULL);
    		return;
    	}
    	
    	if(p==1)
    	{
    		p=0;
    		return;
    	}
    }
    Cioè facendo partire immediatamente il thread e settare quando necessario la variabile p per fermarlo, senza fare altro.
    Ma questo mi da dei problemi quando voglio che alla chiusura della finestra di dialogo(metodo OnClose) il thread si interrompa, in quanto non posso beccare il momento esatto in cui l'oggetto CWinThread viene deallocato, e quindi quando posso effettivamente distruggere CMyDlg...

  2. #2
    Risolto.
    In pratica serve una funzione che permetta il libero scorrimento dei messaggi:
    codice:
    int PumpMessages(void)
    {
        MSG msg;
    	
        while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
        {
            if (AfxGetApp()->PumpMessage() == FALSE)
            {
                AfxPostQuitMessage(0);
                return FALSE; 
            }
        }
        
        // let MFC do its idle processing
       LONG lIdle = 0;
    
       while (AfxGetApp()->OnIdle(lIdle++) == TRUE);
    
       return TRUE;
    }
    e chiamarla modificando il codice così:
    codice:
    CMyDlg::OnButton1()
    {
    	if (p==0)
    	{
    		p=1;
    		c=AfxBeginThread(MyControllingFunction,this,0,0, CREATE_SUSPENDED, NULL);
    		c->m_bAutoDelete=FALSE;
    		c->ResumeThread();
    		return;
    	}
    	
    	if(p==1)
    	{
    		p=0;
    		do{
    		PumpMessages();
    		}while(WaitForSingleObject(c->m_hThread,0)!=WAIT_OBJECT_0);
    		delete c;
    		return;
    	}
    }

  3. #3
    A quanto ho capito questo problema è dovuto in sostanza al fatto che la funzione del thread usa metodi e variabili membro dell'oggetto CMyDlg, il quale però è fermo alla funzione WaitForSingleObject che ha parametro INFINITE, quindi il thread non riesce a proseguire perché i suoi messaggi a CMyDlg sono bloccati.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.