Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Přepsání argumentu ve vláknu

Aktivity
Avatar
Oldřich Beneš:7.12.2016 22:48

Zdravím, potřeboval bych menší radu :). Mám problém při multitaskingu, jedná se mi o to, že ve funkci kterou spustím pomocí vlákna a předám ji argument, tak se mi ten zadaný argument po proběhnutí funkce nezmění tak jak by měl. Viz. kód.

// LuldaOS.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <thread>
#include <ios>
#include <string.h>
#include <string>
#include <list>
#include <iterator>



using namespace std;

//slouží jen pro načtení v pozdějším průběhu převedeno na pole, pro použití sort alg...



//převzato z http://www.cplusplus.com/forum/beginner/12089/
bool compareNoCase(string first, string second)
{
        int i = 0;
        while ((i < first.length()) && (i < second.length()))
        {
                if (tolower(first[i]) < tolower(second[i])) return true;
                else if (tolower(first[i]) > tolower(second[i])) return false;
                i++;
        }

        if (first.length() < second.length()) return true;
        else return false;
}





void sort(char sign, list<string> l) {
        if (sign == 'v' || sign == 's') {
                l.sort(compareNoCase);
        }
        if (sign == 's') l.reverse();
}

void sortZA(list<string> lst) {
        lst.sort();
        lst.reverse();
}



int main()
{
        char temp[45];

        FILE * file;
        file = fopen("C:\\Users\\CaptainMorgan\\Desktop\\Jmena", "r");
        list<string> lst1;
        list<string> lst2;
        //načtení jmen do dvou listů, přibližně na půl...
        int index = 0;
        while (!feof(file)) {
                char word_length = getc(file);
                if (fgets(temp, word_length + 1, file)) {
                        string s(temp);
                        if (index % 2 == 0) lst1.push_front(s);
                        else lst2.push_front(s);
                        index++;
                }
        }

        thread first(sort, 's', lst1);
        //thread second(sortAZ);


        first.join();
        //second.join();


        getchar();
        return 0;
}

Jedná se mi o lst1, potřebuji aby mi ho vlákno seřadilo a zároveň přepsalo.
Děkuji za každou radu :).

 
Odpovědět
7.12.2016 22:48
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Oldřich Beneš
Martin Dráb:7.12.2016 22:57

Předávej ty listy referencí, ne hodnotou. Takhle se celé zkopírují a tyto kopie se pak použijí jako argumenty těch funkcí sort. Změny se nepropagují zpátky.

Mohlo by stačit změnit signatury těch funkcí nějak takto:

void sort(char sign, list<string> & l)
void sortZA(list<string> & lst)

Podobně to můžeš udělat u compareNoCase, pokud to překladač sežere. Protože takhle při každeém porovnávání ty řetězce kopíruješ, což není zrovna nenáročná operace.

bool compareNoCase(const string & first, const string & second)
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
7.12.2016 22:57
2 + 2 = 5 for extremely large values of 2
Avatar
Odpovídá na Martin Dráb
Oldřich Beneš:7.12.2016 23:01

Takto to ale bohužel nefunguje :/

 
Nahoru Odpovědět
7.12.2016 23:01
Avatar
Oldřich Beneš:7.12.2016 23:16

Aha :) problém je v tom, že ta daná funkce nefunguje ve vláknu. Lze jiným způsobem vytvořit vlákno?

 
Nahoru Odpovědět
7.12.2016 23:16
Avatar
martanec
Člen
Avatar
martanec:8.12.2016 8:50

Skus toto:

thread first(sort, 's', std::ref(lst1));

samozrejmostou je tiez aj rada, ktoru ti vyssie dal Martin Drab ohladom predavania hodnot do funkcii cez referencie, nie kopirovanim

 
Nahoru Odpovědět
8.12.2016 8:50
Avatar
Oldřich Beneš:9.12.2016 16:16

Ano, už vyřešeno. Děkuji Vám :)

 
Nahoru Odpovědět
9.12.2016 16:16
Avatar
Odpovídá na martanec
Oldřich Beneš:13.12.2016 20:04

Zdravím, vyskytl se mi problém, mám napsaný kód, který se mi zdál funkční, ale dnes při kontrole mi bylo řečeno, že nefunguje správně, nevrací stejný počet jmen a mám prý někde problém se sortem... Čučím na to už 5 hodin a na nic jsem nepřišel. Nekoukl by mi na to někdo prosím ?

// LuldaOS.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <thread>
#include <ios>
#include <string.h>
#include <string>
#include <list>
#include <windows.h>




using namespace std;

//převzato z http://www.cplusplus.com/forum/beginner/12089/
bool compareNoCase(string first, string second)
{
        unsigned int i = 0;
        while ((i < first.length()) && (i < second.length()))
        {
                //v if a else if pouze porovnává jednotlivé znaky slov, když je jedno z nich menší/větší vrátí true/false, ukončí cyklus....
                //když jsou písmena rovna, zvýším si index pro pohyb v "poli" a pokračuju dál v cyklu
                if (tolower(first[i]) < tolower(second[i])) return true;
                else if (tolower(first[i]) > tolower(second[i])) return false;
                i++;
        }
        //v případě, že budou stejná písmena vrátí kratší slovo, v případě že je první kratší/true
        if (first.length() < second.length()) return true;
        else return false;
}




//metoda pro samotné třídění, jako parametr bere znak, jak třídit a samotný list
void sort(const char sign, list<string> &lst) {
        //ověření, zda je znak v nebo s, provedu sort
        if (sign == 'v' || sign == 's') {
                lst.sort(compareNoCase);
                //když chceme třídit sestupně převrátím předchozí sort
                if (sign == 's') lst.reverse();
        }

}


//metoda pro slívání dvou listů(2první arg), následně znak třídění, cestu k výstupnímu souboru
void sliti(list<string> &l1, list<string> &l2, const char sign, const char * path) {
        FILE * output;
        output = fopen(path,"w+");

        //porovnávám, jak mám třídit, když vzestupně nastavím sort na false... viz další kroky
        bool sort = false;
        if (sign == 'v') {
                //vzestupně
                sort = true;
        }

        int pokus = 0;


        size_t ctemp;
        while (true) {
                //ověřuji zda není jeden z listů prázdný
                if (l1.size() == 0 && l2.size() == 0) break;
                if (l1.size() > 0 && l2.size() > 0) {
                        if (sort) {
                                //porovnávání prvních slov z listů
                                if (compareNoCase(l1.front(), l2.front())) {
                                        ctemp = l1.front().length(); //zjistím délku slova
                                        fprintf(output, "%x%s", ctemp,l1.front().c_str()); //tisk délky slova a samotného slova
                                        l1.pop_front(); // ostranění prvku z listu
                                        pokus++;
                                }
                                else {
                                        ctemp = l2.front().length();
                                        fprintf(output, "%x%s", ctemp, l2.front().c_str());
                                        l2.pop_front();
                                        pokus++;
                                }
                        }

                        else {
                                if (!compareNoCase(l1.front(), l2.front())) {
                                        ctemp = l1.front().length();
                                        fprintf(output, "%x%s", ctemp, l1.front().c_str());
                                        l1.pop_front();
                                        pokus++;
                                }
                                else {
                                        ctemp = l2.front().length();
                                        fprintf(output, "%x%s", ctemp, l2.front().c_str());

                                        l2.pop_front();
                                        pokus++;
                                }
                        }
                }

                //tady nastal případ že jeden z listů je prázný => vypíšu zbytek druhého listu do výstupu...

                //l1 je prázný => vypíšu l2
                else if (l1.size() == 0 && l2.size()>0) {
                        for (unsigned int i = l2.size(); i > 0; i--) {
                                ctemp = l2.front().length();
                                fprintf(output, "%x%s", ctemp, l2.front().c_str());
                                l2.pop_front();
                                pokus++;
                        }

                }

                //l2 je prázdný vypíšu zbytek l1
                else if (l2.size() == 0 && l1.size() > 0) {
                        for (unsigned int i = l1.size(); i > 0; i--) {
                                ctemp = l1.front().length();
                                fprintf(output, "%x%s", ctemp, l1.front().c_str());
                                l1.pop_front();
                                pokus++;
                        }

                }
        }
        int b = pokus;
        fclose(output);
}

//cesta k souboru, list 1, list 2
void nactiJmena(string path, list<string> &l1, list<string> &l2) {
        char temp[45];  //buffer pro načítání jmen ze souboru
        FILE * file;
        file = fopen(path.c_str(), "r");
        //list do kterého se načtou všechna jména
        list<string> templist;

        while (!feof(file)) {
                //zjistím si délku slova
                char word_length = getc(file);

                //vyzkouším načíst daný počet znaků ( jméno )
                if (fgets(temp, word_length + 1, file)) {
                        string s(temp);
                        templist.push_front(s);
                }
        }
        fclose(file);

        //rozdělení do dvou listů

        int index = 0;
        while (templist.size() > 0) {
                if (index % 2 == 0) {
                        l1.push_front(templist.front());
                        templist.pop_front();
                }
                else {
                        l2.push_front(templist.front());
                        templist.pop_front();
                }

                index++;
        }

}

int main(int argc, char* argv[])
{

        //načtení parametrů z konzole
        string pathin = argv[1];
        string pathout = argv[2];
        char * sortsign = argv[3];

        //listy sloužící pro ukládání načtených jmen
        list<string> mylist1;
        list<string> mylist2;

        nactiJmena(pathin, std::ref(mylist1), std::ref(mylist2));

        thread first(sort, sortsign[0], std::ref(mylist1));
        thread second(sort, sortsign[0], std::ref(mylist2));

        //počkání na ukončení práce vláken
        first.join();
        second.join();

        //provedení slití
        sliti(mylist1, mylist2, sortsign[0], pathout.c_str());

        cout << "Aplikace ukončila práci, zadejte libovolný znak a stiskněte enter" << endl;


        getchar();
        return 0;
}
 
Nahoru Odpovědět
13.12.2016 20:04
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.