Ir ao conteúdo
  • Cadastre-se

multitarefa: como fazer 1 multitarefa sem perder dados?


Cambalinho

Posts recomendados

eu fiz 1 classe Multithread para me facilitar a utilizaçao da multitarefa:

class Multithread
{
private:
    HANDLE hThread=NULL;
    DWORD dwThreadId=0;
    bool blnSingleThreadAtTime=false;
    function<void()> multithreadfunction=NULL;
    function<void(LPVOID param)> multithreadparameterfunction=NULL;
    HANDLE myEvent = CreateEvent(0, 0, 0, 0);

    struct mytread
    {
        Multithread *classpointer=NULL;
        LPVOID multithreadparameters=NULL;
    };
    mytread mtparameterthread;

public:

    void SingleThreadAtTime(bool SingleThread)
    {
        blnSingleThreadAtTime=SingleThread;
    }

    bool SingleThreadAtTime()
    {
        return blnSingleThreadAtTime;
    }

    void WaitCondition()
    {
        WaitForSingleObject(myEvent, INFINITE);
    }

    void SetCondition()
    {
        SetEvent(myEvent);
    }

    static DWORD WINAPI MyThreadFunction( LPVOID lpParam )
    {
        static bool blnfirsttime=false;
        Multithread *pThis = static_cast<Multithread*>(lpParam);
        if(pThis->blnSingleThreadAtTime==true && blnfirsttime==true)
            pThis->WaitCondition();
        blnfirsttime=true;
        pThis->multithreadfunction();
        if(pThis->blnSingleThreadAtTime==true && blnfirsttime==true)
            pThis->SetCondition();
        return 0;
    }

    static DWORD WINAPI MyParameterThreadFunction( LPVOID lpParam )
    {
        static bool blnfirsttime=false;
        mytread *pThis = static_cast<mytread*>(lpParam);
        if(pThis->classpointer->blnSingleThreadAtTime==true && blnfirsttime==true)
            pThis->classpointer->WaitCondition();
        blnfirsttime=true;
        pThis->classpointer->multithreadparameterfunction(pThis->multithreadparameters);
        if(pThis->classpointer->blnSingleThreadAtTime==true && blnfirsttime==true)
            pThis->classpointer->SetCondition();
        delay(100);
        return 0;
    }

    Multithread(std::function<void()> SetFunction)
    {
        multithreadfunction=SetFunction;
    }

    Multithread( function<void(LPVOID)> SetFunction )
    {
        multithreadparameterfunction =SetFunction;
    }

    //corrigir
    template<typename tpVariant>
    Multithread( function<void(tpVariant)> SetFunction )
    {
        multithreadparameterfunction = [=]( LPVOID pv ) { SetFunction( static_cast<tpVariant>( pv ) ); };
    }

    template<typename tpVariant>
    void operator ()(tpVariant &vrParam)
    {

        LPVOID lpParam=static_cast<LPVOID>(&vrParam);
        mtparameterthread.classpointer=this;
        mtparameterthread.multithreadparameters=lpParam;

        hThread= CreateThread(
            NULL,                   // default security attributes
            0,                      // use default stack size
            Multithread::MyParameterThreadFunction,       // thread function name
            static_cast<LPVOID>(&mtparameterthread),          // argument to thread function
            0,                      // use default creation flags
            &dwThreadId);
        delay(100);
    }


    void operator ()(LPVOID vrParam)
    {
        mtparameterthread.classpointer=this;
        mtparameterthread.multithreadparameters=vrParam;

        hThread= CreateThread(
            NULL,                   // default security attributes
            0,                      // use default stack size
            Multithread::MyParameterThreadFunction,       // thread function name
            static_cast<LPVOID>(&mtparameterthread),          // argument to thread function
            0,                      // use default creation flags
            &dwThreadId);
        delay(100);
    }

    void operator ()()
    {
       hThread  = CreateThread(
            NULL,                   // default security attributes
            0,                      // use default stack size
            &Multithread::MyThreadFunction,       // thread function name
            this,          // argument to thread function
            0,                      // use default creation flags
            &dwThreadId);
        delay(100);
    }

    ~Multithread()
    {
        CloseHandle(hThread);
        CloseHandle(myEvent);
    }
};

a partir daqui fiz 1 funçao para input:

Multithread mtRead{ [&]( LPVOID varname)
    {
        blnread=true;
        string *strTest=static_cast<string*>(varname);
        ostringstream  address;
        address << strTest;
        std:string name = address.str();
        DebugText(name);
        while(blnread==true)
        {
            MSG TMsg;
            do
            {
                if(blnread==false)
                    break;
                TranslateMessage(&TMsg);
                if(blnread==false)
                    break;
                DispatchMessage(&TMsg);
                if(blnread==false)
                    break;
            }
            while (PeekMessage(&TMsg, 0, 0, 0, true) || (blnread==true));
        }

        *strTest=readstring;
        readstring="";
    }};


void read(string &txttext)
    {
        CHARFORMAT2 cf ;
        cf.cbSize = sizeof( CHARFORMAT2 ) ;
        cf.dwMask = CFM_COLOR | CFM_BACKCOLOR | CFM_EFFECTS2 ;
        cf.crTextColor =clrTextColor;
        cf.dwEffects =0;
        cf.crBackColor = clrTextBackColor;
        SendMessage(consoleedit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf );
        mtRead(static_cast<LPVOID>(&txttext));
    }

imagina chamar a funçao read() varias vezes... agora observe o output do endereço da variavel que irá receber o novo valor:

 

Citar

before read: 0x28facc
before read2: 0x28fac4
before read3: 0x28fac0
0x28facc
0x28fac0
0x28fac0

 

a minha questao é: porquê é que estou a perder os endereços da variavel?(0x28fac4)

eu estou a tentar fazer tudo o que sei sobre programaçao, mas nao consigo entender bem o que se passa.... talvez a:

mtRead(static_cast<LPVOID>(&txttext));

nao esteja a proteger bem o endereço da variavel... mas nao sei. alguem me pode explicar?

Link para o comentário
Compartilhar em outros sites

Salve salve Cambalinho, quanto tempo!

 

Olha, eu tenho a impressão que na sua função mtRead() o compilador não pode garantir o mesmo endereço durante o cast,

 

string *strTest=static_cast<string*>(varname);

 

porque o que você tá dizendo é o seguinte: crie um novo pointer do tipo string* chamado varname (isso ocorre dentro do static_cast) e então atribua esse novo pointer a outro pré existente chamado strTest. 

 

Talvez, se ao invés disso, você atribuir o endereço original de varname:

string *strTest=static_cast<string>(&varname);
Link para o comentário
Compartilhar em outros sites

salve salve

honestamente eu ja descobri o problema e ja o resolvi. talvez a sua ideia esteja correcta, mas eu perdia sempre o endereço da variavel devido a outro problema: o mtparameterthread, todas vezes que usava '()', os valores eram sempre alterados e isso é que me dava problemas. como resolvi? criei 1 vector e agora ja nao os perco ;)

outra coisa: o pc nao me garante 1 multitarefa por ordem de chamada, como resolvi? meti 1 delay() apos o CreateThread() e agora funciona 5* ;)

muito obrigado por tudo

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!