abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 06:00 | Pozvánky

Srpnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 22. 8. 2019 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tématem bude jako obvykle svobodný software a hardware. A pokud vás zajímá bezpečnost bezdrátových klávesnic a myší (útok MouseJack a spol.) a nějaké takové zařízení máte, vezměte ho sebou – trochu ho potrápíme o ověříme jeho bezpečnost.

xkucf03 | Komentářů: 0
včera 16:33 | Nová verze

David Heinemeier Hansson oznámil vydání nové major verze 6.0 frameworku pro vývoj webových aplikací Ruby on Rails (Wikipedie). Přehled novinek v příspěvku na blogu a v poznámkách k vydání. Přispělo 801 vývojářů.

Ladislav Hagara | Komentářů: 2
17.8. 18:11 | Nová verze

Byla vydána verze 2.23.0 distribuovaného systému správy verzí Git. Přispělo 77 vývojářů, z toho 26 nových. Přehled novinek v poznámkách k vydání nebo v příspěvku na blogu GitHubu.

Ladislav Hagara | Komentářů: 7
17.8. 13:33 | Komunita

Nadace Raspberry Pi na svém blogu informuje o vydání Scratch 3 Desktopu pro Raspbian na Raspberry Pi. Verze 3 výukového vizuálního programovacího jazyka Scratch byla vydána v lednu letošního roku. Offline Scratch Desktop byl ale dosud dostupný pouze pro Windows a macOS.

Ladislav Hagara | Komentářů: 0
15.8. 19:44 | Bezpečnostní upozornění

Byly zveřejněny informace o 8 bezpečnostních chybách v implementacích protokolu HTTP/2. Chyby CVE-2019-9511 až CVE-2019-9518 lze zneužít k odepření služeb (DoS). Přehled softwarových produktů a v nich obsažených chyb v tabulce na stránce CERT/CC.

Ladislav Hagara | Komentářů: 16
15.8. 17:55 | Nová verze

Byla vydána verze 1.37.0 programovacího jazyka Rust (Wikipedie). Podrobnosti v poznámkách k vydání. Vyzkoušet Rust lze například na stránce Rust by Example.

Ladislav Hagara | Komentářů: 100
15.8. 15:11 | Nová verze

Byla vydána nová verze 19.08.0 KDE Aplikací (KDE Applications). Přehled novinek v kompletním seznamu změn a na stránce s dalšími informacemi. Videoukázka nových vlastností na YouTube nebo na PeerTube.

Ladislav Hagara | Komentářů: 5
15.8. 14:44 | Zajímavý projekt

CutiePi je open source tablet postavený na Raspberry Pi, konkrétně na Compute Module. K dispozici by měl být koncem roku. Cena zatím nebyla stanovena. Vývojový tým zjišťuje zájem [Hacker News].

Ladislav Hagara | Komentářů: 8
14.8. 21:33 | Zajímavý článek

Greg Kroah-Hartman v příspěvku na svém blogu popisuje svou práci na linuxovém jádře. Popis prokládá videoukázkami ve formátu asciinema. Dnes používá především poštovního klienta Mutt. V plánu má přejít na poštovního klienta aerc, pokud do něj budou přidány v popisu zmíněné vlastnosti.

Ladislav Hagara | Komentářů: 0
14.8. 21:11 | Nová verze

Bylo oznámeno, že EPEL (Extra Packages for Enterprise Linux) ve verzi 8.0 je připraven k vydání. Vedle x86_64, ppc64le a aarch64 je nově podporována také platforma s390x.

Ladislav Hagara | Komentářů: 0
Používáte ještě 32bitový software na PC?
 (20%)
 (15%)
 (17%)
 (43%)
 (6%)
 (29%)
Celkem 427 hlasů
 Komentářů: 36, poslední včera 21:46
Rozcestník

Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

20. 4. 2009 | David Watzke | Programování | 11752×

V tomto díle se dozvíte, jak kontrolovat vstupní textová pole pomocí regulárních výrazů, jak a kdy používat vlákna a jak zobrazovat průběh nějaké déle trvající operace.

Regulární výrazy

Pro práci s regulárními výrazy Qt poskytuje třídu QRegExp. Ukázkový program, který jsem pro vás připravil, umožňuje zvolit si typ výrazu (rozšířený regulární výraz, rozšířený regulární výraz s hladovými (greedy) kvantifikátory, výraz s žolíkovými znaky (wildcards) nebo pevný řetězec, což je totéž jako regulární výraz použitý na řetězec s escapovanými metaznaky).

regex.h: API.

#ifndef REGEX_H
#define REGEX_H

#include <QWidget>

class QCheckBox;
class QComboBox;
class QLabel;
class QLineEdit;
class QRegExp;

class Regex : public QWidget
{
	Q_OBJECT

public:
	Regex(QWidget *parent = 0);

private:
	QCheckBox* caseCheckbox;
	QComboBox* syntaxCombo;
	QRegExp* regex;
	QLabel* regexIcon;
	QLabel* stringIcon;
	QLineEdit* regexLine;
	QLineEdit* stringLine;

private slots:
	void changeSyntax(int);
	void changeCaseSensitivity(int);
	void checkString(QString);
	void checkRegex(QString);
};

#endif // REGEX_H

regex.cpp: Pro vyhledání daného výrazu v řetězci vytvoříme instanci třídy QRegExp, které nastavíme požadovaný výraz buď při vytváření přes konstruktor, nebo pomocí metody setPattern() a následně zavoláme metodu indexIn(), které předáme řetězec. V případě žolíkových znaků musíme místo indexIn() vždy volat exactMatch(), což je metoda jinak sloužící ke zjištění přesné shody, tzn. volání exactMatch("string") při použití regulárních výrazů odpovídá indexIn("^string$"). Metoda indexIn() vrací index (int), na kterém byl začátek výrazu nalezen (nebo -1 v případě nenalezení), zatímco exactMatch() vrací bool odrážející úspěch hledání.

#include "regex.h"

#include <QCheckBox>
#include <QComboBox>
#include <QGridLayout>
#include <QLabel>     
#include <QLineEdit>  
#include <QRegExp>    
#include <QStyle>     

Regex::Regex(QWidget *parent)
	: QWidget(parent), regexIcon(new QLabel), stringIcon(new QLabel)
{                                                                       
	// QRegExp objekt pro práci s regulárními výrazy                
	regex = new QRegExp(QString(), Qt::CaseInsensitive);            
	
	// nabídka syntaxí
	syntaxCombo = new QComboBox;
	syntaxCombo->addItem(tr("RegExp"), QRegExp::RegExp);
	syntaxCombo->addItem(tr("RegExp2"), QRegExp::RegExp2);
	syntaxCombo->addItem(tr("Wildcard"), QRegExp::Wildcard);
	syntaxCombo->addItem(tr("FixedString"), QRegExp::FixedString);
	
	// zaškrtávací pole určující rozlišování malých/velkých písmen
	caseCheckbox = new QCheckBox(tr("Case sensitive"));           
	// vstupní pole pro regulární výraz a řetězec                 
	regexLine = new QLineEdit;                                    
	stringLine = new QLineEdit;                                   
	
	// propojíme ovládací prvky tak, aby změny na nich zpracovaly naše sloty
	connect(syntaxCombo, SIGNAL(activated(int)), this, SLOT(changeSyntax(int)));
	connect(caseCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeCaseSensitivity(int)));
	connect(regexLine, SIGNAL(textChanged(QString)), this, SLOT(checkRegex(QString)));       
	connect(stringLine, SIGNAL(textChanged(QString)), this, SLOT(checkString(QString)));     
	
	// teprve teď (po propojení signálů se sloty) nastavíme výchozí text,
	// aby se rovnou projevily změny                                     
	
	// výchozí reg. výraz pro označení emailové adresy
	regexLine->setText("[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}");
	// výchozí řetězec                                               
	stringLine->setText("qt4@watzke.cz");                         
	
	// vytvoříme mřížkové rozložení
	QGridLayout* layout = new QGridLayout(this);
	// přidáme popisek na 0. řádek, 0. sloupec  
	layout->addWidget(new QLabel(tr("Reg. expression syntax:")), 0, 0);
	layout->addWidget(syntaxCombo, 0, 1);                              
	layout->addWidget(caseCheckbox, 1, 1);                             
	layout->addWidget(new QLabel(tr("Regular expression:")), 2, 0);    
	// přidáme vstupní pole pro reg. výraz na 2. řádek, 1. sloupec        
	layout->addWidget(regexLine, 2, 1);                                
	layout->addWidget(regexIcon, 2, 2);                                
	layout->addWidget(new QLabel(tr("String to match:")), 3, 0);       
	layout->addWidget(stringLine, 3, 1);                               
	layout->addWidget(stringIcon, 3, 2);                               
	
	// toto nastavení layoutu není nutné, když vytvoříme pouze jeden
	// s rodičem "this", nicméně ani neuškodí                       
	setLayout(layout);
	
	// změníme výchozí šířku okna, ale ne napevno
	resize(500, sizeHint().height());
}

// volá se pro kontrolu aktuálního řetězce (zda odpovídá reg. výrazu)
void Regex::checkString(QString newString)
{
	// odpovídá?
	bool match;
	
	// wildcard vyžaduje použití exactMatch(), jinak nefunguje
	if(regex->patternSyntax() == QRegExp::Wildcard)
		match = regex->exactMatch(newString);
	else
		match = (regex->indexIn(newString) >= 0);
	
	// nastavíme ikonu znázorňující zda řetězec odpovídá či neodpovídá
	if(match)
		stringIcon->setPixmap(style()->standardIcon(QStyle::SP_DialogOkButton).pixmap(16, 16));
	else
		stringIcon->setPixmap(style()->standardIcon(QStyle::SP_DialogNoButton).pixmap(16, 16));
}

// volá se pro kontrolu správnosti aktuálního reg. výrazu
void Regex::checkRegex(QString newRegex)
{
	// nastavíme nový regulární výraz
	regex->setPattern(newRegex);
	
	// ověříme správnost reg. výrazu, nastavíme patřičnou ikonku a
	// v případě, že správný je, zkontrolujeme, zda mu řetězec odpovídá
	if(regex->isValid())
	{
		regexIcon->setPixmap(style()->standardIcon(QStyle::SP_DialogOkButton).pixmap(16, 16));
		checkString(stringLine->text());
	} else {
		regexIcon->setPixmap(style()->standardIcon(QStyle::SP_DialogNoButton).pixmap(16, 16));
		// pokud je reg. výraz chybný, nastavíme u řetězce varovnou ikonku
		// signalizující neznámý stav
		stringIcon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(16, 16));
	}
}

// volá se při změně syntaxe reg. výrazu z nabídky
void Regex::changeSyntax(int index)
{
	// získáme data o vybrané položce nabídky
	int newSyntax = syntaxCombo->itemData(index).toInt();
	// a nastavíme vybranou syntaxi
	regex->setPatternSyntax((QRegExp::PatternSyntax)newSyntax);
	
	// nyní je třeba překontrolovat zda aktuální reg. výraz
	// je validní při nově zvolené syntaxi
	checkRegex(regexLine->text());
}

// volá se při změně stavu zaškrtávacího pole
void Regex::changeCaseSensitivity(int state)
{
	if(state == Qt::Checked)
		regex->setCaseSensitivity(Qt::CaseSensitive);
	else
		regex->setCaseSensitivity(Qt::CaseInsensitive);
	
	// po změně nastavení rozlišování malých/velkých písmen zkontrolujeme
	// zda aktuální řetězec stále odpovídá
	checkString(stringLine->text());
}

Qt 4 Regulární výrazy

Vlákna a ukazatel průběhu

Qt podporuje vlákna. Používá vždy nativní implementaci vláken podle platformy (např. POSIX threads, Win32). Dnes si ukážeme pouze naprosto základní a jednoduché použití. Když v programu nepoužíváte vlákna, tak se váš kód obvykle provádí ve vlákně obstarávajícím GUI, které má mj. vlastní smyčku událostí (event loop). To je v pořádku jen do té doby, než se objeví potřeba spustit něco, co bude trvat déle, jako třeba nějaký výpočet. Kdybychom tento výpočet prováděli ve vlákně s GUI, tak by se program po dobu výpočtu z uživatelského hlediska zasekl – přestalo by reagovat uživatelské rozhraní. Jedním z řešení je provést výpočet v odděleném vlákně, což je přesně to, co si teď ukážeme.

Přestože se může zdát jednodušší přistupovat z vlákna ke grafickému rozhraní přímo (například přes předaný ukazatel), vhodnějším řešením je vysílat z vlákna signály, na které bude GUI reagovat. Kód je pak univerzálnější a navíc si tak jasně oddělíme GUI od zbytku programu.

To je pro začátek dost teorie. Jak se tedy vytváří vlákno? Je třeba vytvořit třídu, která dědí QThread a reimplementovat její chráněnou metodu run(), která se provede po spuštění vlákna metodou start().

Následuje zdrojový kód programu, ve kterém zvolíte soubor, čímž se spustí výpočet jeho kontrolního součtu (MD5, MD4 nebo SHA1), přičemž průběh výpočtu bude znázorněn na grafickém ukazateli (QProgressBar).

progress.h: API.

#ifndef PROGRESS_H
#define PROGRESS_H

#include <QWidget>

class QComboBox;
class QLabel;
class QProgressBar;
class ProgressThread;

class Progress : public QWidget
{
	Q_OBJECT

public:
	Progress(QWidget *parent = 0);
	~Progress();

private:
	QComboBox* hashCombo;
	QLabel* hashLabel;
	QProgressBar* progress;
	ProgressThread* thread;

private slots:
	void progressTest();
};

#endif // PROGRESS_H

progress.cpp: Okno programu.

#include "progress.h"                                                 
#include "progressthread.h"                                           

#include <QHBoxLayout>
#include <QVBoxLayout>

#include <QComboBox>
#include <QLabel>   
#include <QPushButton>
#include <QProgressBar>
#include <QFileDialog> 

Progress::Progress(QWidget *parent) : QWidget(parent), thread(0)
{                                                               
	// vytvoříme label (popisek)                            
	hashLabel = new QLabel(tr("Select a file to hash"));    
	// text v labelu lze označit (a zkopírovat do schránky) 
	hashLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
	
	// vytvoříme ukazatel průběhu
	progress = new QProgressBar; 
	
	// vytvoříme tlačítko zahajující výběr souboru
	QPushButton* btn = new QPushButton("...");    
	
	// vytvoříme seznam pro výběr hashovacího algoritmu
	hashCombo = new QComboBox;
	hashCombo->addItem("MD5", QCryptographicHash::Md5);
	hashCombo->addItem("MD4", QCryptographicHash::Md4);
	hashCombo->addItem("SHA1", QCryptographicHash::Sha1);
	
	// propojíme tlačítko se slotem zahajujícím hashování
	connect(btn, SIGNAL(clicked()), this, SLOT(progressTest()));
	
	// do horizontálního rozložení přidáme ukazatel průběhu, seznam a tlačítko
	QHBoxLayout* hLayout = new QHBoxLayout;
	hLayout->addWidget(progress);
	hLayout->addWidget(hashCombo);
	hLayout->addWidget(btn);
	
	// do (hlavního) vertikálního rozložení přidáme připravené horiz. rozložení
	// a pod něj ještě label se stavovou zprávou
	QVBoxLayout* layout = new QVBoxLayout(this);
	layout->addLayout(hLayout);
	layout->addWidget(hashLabel);
	
	// nastavíme výchozí šířku okna na 700px; výška je automaticky zvolená
	resize(700, baseSize().height());
}

Progress::~Progress()
{
	// uklidíme po sobě (pokud je co)
	if(thread && !thread->isRunning())
		delete thread;
}

void Progress::progressTest()
{
	if(thread)
	{
		// pokud vlákno běží
		if(thread->isRunning())
		{
			// informujeme uživatele, že zrovna hashuje a skončíme
			hashLabel->setText(tr("Hashing is in progress!"));
			return;
		}
		else { // jinak smažeme staré vlákno
			delete thread;
		}
	}
	
	// aktualizujeme zprávu ("Čekám na vybrání souboru")
	hashLabel->setText(tr("Waiting for user to select a file"));
	
	// zobrazíme dialog pro výběr souboru
	QString fileName = QFileDialog::getOpenFileName(this);
	// pokud uživatel nic nevybere (zavře dialog), skončíme
	if(fileName.isEmpty())
		return;
	
	// nastavíme zprávu na "Zpracovávám [soubor]"
	hashLabel->setText(tr("Processing ") + fileName);
	
	// vytvoříme vlákno, ve kterém se bude hashovat
	thread = new ProgressThread(fileName, (QCryptographicHash::Algorithm)
					hashCombo->itemData(hashCombo->currentIndex()).toInt());
	// propojíme ukazatel průběhu se signálem hashovacího vlákna
	connect(thread, SIGNAL(updateProgress(int)), progress, SLOT(setValue(int)));
	// propojíme label se signálem vlákna tak, aby zobrazoval příchozí zprávy
	connect(thread, SIGNAL(message(QString)), hashLabel, SLOT(setText(QString)));
	// spustíme vlákno
	thread->start();
}

progressthread.h: API vlákna.

#ifndef PROGRESSTHREAD_H
#define PROGRESSTHREAD_H

#include <QCryptographicHash>
//#include <QDebug>
#include <QThread>

class QFile;

class ProgressThread : public QThread
{
	Q_OBJECT
public:
	ProgressThread(QString, QCryptographicHash::Algorithm);
//      ~ProgressThread() { qDebug() << "terminating the thread"; }

private:
	QFile* file;
	QCryptographicHash::Algorithm m_hashtype;

protected:
	void run();

signals:
	void message(QString);
	void updateProgress(int);
};

#endif // PROGRESSTHREAD_H

progressthread.cpp: vlákno, ve kterém probíhá hashování.

#include "progressthread.h"

#include <QFile>

ProgressThread::ProgressThread(QString fileName, QCryptographicHash::Algorithm hashtype)
{
	// vytvoříme objekt pro manipulaci se souborem
	file = new QFile(fileName, this);
	// uložíme si zvolený hashovací algoritmus
	m_hashtype = hashtype;
}

void ProgressThread::run()
{
	// otevřeme soubor pro čtení
	if(!file->open(QIODevice::ReadOnly | QIODevice::Unbuffered))
	{
		// pokud nelze otevřít, informujeme uživatele
		emit message(tr("Couldn't open ") + file->fileName());
		return;
	}
	
	// objekt obstarávající hashování
	QCryptographicHash* hash = new QCryptographicHash(m_hashtype);
	QByteArray buffer;
	// velikost bufferu (512 KiB)
	// qint64 je na všech platformách, kde běží Qt, zaručeně 64bitový integer,
	// jehož literál lze vytvořit pomocí makra Q_INT64_C
	qint64 bufSize = Q_INT64_C(512*1024);
	// 1 % je step bajtů
	qint64 step = file->size() / 100;
	// přečteno bajtů
	qint64 read = 0;
	// procenta průběhu
	int percent = -1;
	
	// dokud je co číst
	while(!(buffer = file->read(bufSize)).isEmpty())
	{
		// hashujeme data po jednotlivých bufferech
		hash->addData(buffer);
		// ukládáme si kolik bajtů už je zpracováno
		read += buffer.size();
		// pokud se změnilo procentu průběhu, vyšleme signál
		if((read / step) != percent)
		{
			percent = read / step;
			emit updateProgress(percent);
		}
	}
	
	// ujistíme se, že ukazatel průběhu ukáže 100% po dokončení
	// (i když je soubor menší než buffer)
	if(percent != 100)
		emit updateProgress(100);
	
	// vyšleme signál s hashem
	emit message(file->fileName() + ": " + hash->result().toHex());
	
	// uklidíme po sobě
	delete hash;
}

Qt 4 progressbar thread, Ukazatel průběhu hashování

K vláknům se ještě určitě vrátíme, protože jde o dost obsáhlé téma. S tímto si vystačíte jen pro různé jednoduché úkony, které je třeba provádět na pozadí. Na závěr mám ještě jeden tip. Pokud vaše vlákno nemá smyčku událostí (tzn. nespustili jste exec()) a chcete zničit instanci vlákna poté, co se vykoná run(), tak přidejte do konstruktoru vlákna toto propojení:

connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));

Závěr

V příštím díle si kromě jiného ukážeme, jak do GUI přidat karty (taby), jak v programu otevřít nové okno (například s nastavením) a řekneme si něco o modálnosti oken. Těšit se můžete také na ukázku použití WebKitu pro prohlížení webu a Phononu pro přehrávání zvuku.

       

Hodnocení: 100 %

        špatnédobré        

Nástroje: Tisk bez diskuse

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

20.4.2009 01:05 dad
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

k tem vlaknum: myslim ze plati zasadni poucka, ze pro to, aby programy pouzivajici vlakna fungovaly stabilne je zapotrebi ty vlakna z programu odstranit.

Rad bych se zeptal GUI kolegu, jestli vidi skutecne praktickou nutnost vlakna pouzivat, jak v clanku naznaceno a nebo jestli to vidi jako ja - ze je to jen skolska teorie, ktera prinasi jen problemy?

20.4.2009 01:52 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
dovolim si parafrazovat jeden stary vtip:
Programming multithreaded applications is like teenage sex:
  • It is on everyone's mind all the time.
  • Everyone talks about it all the time.
  • Everyone thinks everyone else is doing it.
  • Almost no one is really doing it.
  • The few who are doing it are: A. Doing it poorly. B. Sure it will be better next time. C. Not practising it safely.
programovani paralelnich aplikaci soucasnymi mainstreamovymi prostredky je neco tak efektivniho a zabavneho jako programovani v assembleru... ale blyska se na casy... za par let se mozna konecne podari zahodit celou koncepci vlaken, zamku a podobnych nesmyslu a prejit na rozumnejsi uroven abstrakce...
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
20.4.2009 08:44 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
k tem vlaknum: myslim ze plati zasadni poucka, ze pro to, aby programy pouzivajici vlakna fungovaly stabilne je zapotrebi ty vlakna z programu odstranit.
Přesně tak. Není lepší způsob, jak provádět dlouhý výpočet, než spustit ho na jednom procesoru a nechat tři ostatní nedělat nic.
Quando omni flunkus moritati
Marek Bernát avatar 20.4.2009 11:18 Marek Bernát | skóre: 17 | blog: Arcadia
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Hovoril o stabilite, nie o výkone, takže sa s ním nedá než súhlasiť. Samozrejme s výnimkou, že programátor je paralelný guru, ktorý presne vie, čo robí. A to je vskutku bežný prípad ;-)

physics.stackexchange.com -- Q&A stránky o fyzike v štýle StackOverflow.
20.4.2009 11:22 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Tak tohle ja si treba vubec nemyslim. Ja si myslim presny opak-skolska teorie je to, ze vsechny programy lze napsat bez pouziti vice vlaken aniz by to uzivatel nepoznal.

Rozdeleni procesu do vicevlaken vam totiz umozni podstatneji lepe a jemneji clenit procesorovy cas, mene dulezitym a dele trvajicim vecem dat nizsi prioritu a pritom zachovat vysokou reaktivitu GUI. Toho pri vyuzivani IDLE smycek apod. nejste schopen dosahnout.Jeden priklad - Opera vs. Firefox. Opera vlakna pouziva, Firefox ne. Kdyz si ve firefoxu behem prohlizeni stranky na pozadi otevru tab, cely prohlizec nekdy i na tri sekundy zamrze (hezky priklad je hlavni stranka wikipedie) a prestane reagovat, protoze nejaka dele tvrajici operace si zabere hlavni vlakno a smitec. Kdezto opera ho otevre hezky v druhem threadu na pozadi (a dokonce to dela druhe jadro) a ja se nemusim rozcilovat, ze me puvodni stranka prestane reagovat na scrolling.

Bylo to napsane i v clanku - lepe od sebe oddelite vykonne veci a graficke. Vemte si,ze budete mit treba slozitou matematickou rutinu, ktera bude trvat treba minutu. Po tu dobu by vas program byl zamrzly a neragoval by vam ani na tlacitka ani na udalosti, ktere maji prekreslovat hlavni okno. To je sileny, kdybyste takovy program dal koncovemu uzivateli, hodi vam ho na hlavu. Musel byste periodicky volat metodu, ktera bude zpracovavat zpravy. Jednak si tim do ciste matematicke rutiny, ktera nema s GUI nic spolecneho pridate vazbu na GUI. Jiste,udelate to callbackem, ale kdyz se ta rutina bude skladat z mnoha kroku, budete muset to volani callbacku pridat do vsech casti a totalne si ten kod zaplevelite nesmyslem. A navic, jak urcite, jak casto budete tu ProcessMessages metodu volat? Kdyz ji budete volat hodne casto, snizite si vykon prave tim nesmyslne castym volanim. Kdyz ji budete volat malo casto, nebude se vam dostatecne rychle prekreslovat okno a budete pred uzivatelem vypadat jako patlal. Kdyz ale tu vypocetni rutinu date do samostatneho vlakna, nemusite to resit a budete mit cisty a rychly kod a okamzitou reakci GUI. Take vas to nepresvedci?

A treti priklad jsem sam resil. Delal jsem aplikaci neco na zpusob google earth (s vizualizaci nejakych geologickych dat do mapy). Tady je to uz naprosto nemozne napsat bez dalsiho vlakna, aniz by ten program neztrail na pouzitelnosti. Predstavte si, ze chcete mysi v realnem case posouvat mapu, ktera se nacita z disku a neco se do ni vizualizuje. Tech map nacitanych z disku je hodne a nekdy trva i dve sekundy nez se vsechna viditelna data nactou z disku a dekomprimuji. Dokazete si predstavit odezvu takoveho programu, kdyby byl napsany v jednom vlakne? Protoze napr. z google earth jste zvykly, ze muzete posuvat mapu i v prubehu nacitani. Verte mi zkousel jsem to napsat i do jednoho vlakna, ale ta reaktivnost na pohyb mysi byla otresna - protoze nacteni pngu z disku a jeho dekodovani jsou dost dlouha casova kvanta a velmi spatne se deli. Opravdu, nacitat data a pritom zarucit uzivateli dostatecne rychlou odezvu (i kdyz neni mapa nactena cela) je s pouzitim vice threadu opravdu neporovnateny rozdil (a v dusledku je to i snazsi) nez s jednim (a na vice procesorech je to znat o to vic).

Takze spis bych rekl, ze nazory, ktere jsem tady cetl pisi lide, kteri se vlaken boji a/nebo je nehapu. Jiste, je potreba hlidate racy a deadlocky, ale da se to naucit a pri dobrem rozcleneni si muzete vystacite v podstate jenom s mutexy. Mozna to ale vidim jednoduse ja, protoze jsem spis RTOS programator a v embedded RT aplikacich se bez dokonale znalosti programovani vice vlaken neobejdete, ale stejne se s nazory v tomto vlakne nemuzu ztotoznit.

 

 

 

 

 

 

20.4.2009 12:44 dad
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

velmi vystizna a vecna reakce - dekuji.

Rad bych z te prakticke stranky pripomnel, ze 99% vsech aplikaci na desktopu (za ktere nekdo plati !) jsou aplikace ekonomicke, kde je nejvetsi matematicka operace deleni. To k tomu vasemu prikladu c. 1 s tou komplikovanou vypocetni funkci.

Kolik programatoru dela prohlizec? Nebo googlr earth? V takovych pripadech mate absolutne pravdu, tam by bylo z uzivatelskeho duvodu jiste sproste, nechat uzivatele cekat. I kdyz , jak pisete, firefox si to dovoli? Ma opera mnohem vice uzivatelu, kdyz ma ty vlakna?

Nechci polemizovat, ale myslim si, ze je to silne specificka vec a jak by rekl Karel Zak, u Postgresql jsou radi, ze server udelali jako viceprocesni a ne jako vicevlaknovou aplikaci.

U tech beznych aplikaci jde o to, ze uzivatel provede nejakou akci (napr. si necha zobrazit v pdf fakturu, ktero chce odeslat) a kdyby to melo trvat dlouho, tak by mu vlakna umoznila, delat neco jineho. Ale co by delal? Zacel by zpracovavat nejakou jinou zakazku, v pulce by mu vyskocila ta faktura z te predchozi ....Proto jsem napsal, ze se jedna o teorie ( a jak jste doplnil vy) i o par specialnich pripadu.

P.S.

Ozval jsem se, nebot autor zacne relativne brzy s vlakny a vubec se zatim nemluvilo o tom, co je skutecne bezne potreba. Napr. jak je to s numerickymi policky, jejich editaci - k tomu bylo v dnesnim dile neco o regexp, ale staci to?

20.4.2009 13:37 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Rad bych z te prakticke stranky pripomnel, ze 99% vsech aplikaci na desktopu (za ktere nekdo plati !) jsou aplikace ekonomicke, kde je nejvetsi matematicka operace deleni. To k tomu vasemu prikladu c. 1 s tou komplikovanou vypocetni funkci.

To mate jiste pravdu, ale na druhou stranu- kdyz jsem si precetl cele toto vlakno a nic o tematu nevedel, dospel bych k zaveru, ze vicevlaknove programovani je totalni zlo, ktere se musi za vsech okolnosti zavrhmout a vykorenit. Opravdu to tak pusobi, zejmena dalsi reakce (napr. teenage sex) mi prisla takove, ze si tady nikdo neuvomil prave ty priklady, kdy je vicevlakone programovani neocenitelne (a bohuzel pravdepodobne z neznalosti veci). Proto ta obsahlejsi reakce. Mimochodem dalsi priklad pouziti vice vlaken je vice prizemenjsi-rekl bych, ze pouziti druheho vlakna na komunikaci (napr. ethernet, usb) v GUI(!zduraznuji!) aplikaci je snazsi, nez se snazit narvart selecty/polly do hlavni smycky.

I kdyz , jak pisete, firefox si to dovoli? Ma opera mnohem vice uzivatelu, kdyz ma ty vlakna?

Tak to uz je argumentace trosku jinde. Take nebude argumentovat, ze jsou Windows lepsi nez Linux,protoze Windows ma vice uzivatelu. Opera ma sice mene uzivatelu nez Firefox(mimochodem, ja jej sam pouzivam, kvuli te spouste extensions), ale technicky je Opera urcite lepsi a rychlejsi. Alespon pro me je odezva vicevlaknove opery o 100% lepsi nez Firefoxe. Skoda absence tech extensions... 

Nechci polemizovat, ale myslim si, ze je to silne specificka vec a jak by rekl Karel Zak, u Postgresql jsou radi, ze server udelali jako viceprocesni a ne jako vicevlaknovou aplikaci.

Tak SQL server je opravdu mnohem vhodnejsi pro pouziti ve vice procesech i kdyz by be na druhou stranu zajimalo, jak resi (a jaky overhead) ma komunikace mezi temi procesy (musi si napr. sdelit informace o probihajicich transakcich). Muzete si nasdilet pamet, ale pak uz se vam rozdil mezi vice procesy/vice vlakny docela smaze. Jenomze, tato diskuze nebyla o vlakno vs. proces, ale o tom,zda jsou vlakna zlo nebo ne? Vetsina prispivatelu tvrdi (alespon jak jsem to ja pochopil), ze vlakna jsou dilo satanovo a neni mozne udelat dobry program s vlakny. Ja jsem jednoduse vyjadril jako svuj nazor pravy opak, ze jsou programy, kdy dobry program bez vlaken nenapisete.

Zacel by zpracovavat nejakou jinou zakazku, v pulce by mu vyskocila ta faktura z te predchozi ....Proto jsem napsal, ze se jedna o teorie ( a jak jste doplnil vy) i o par specialnich pripadu.

Samozrejme, toto je naprosto jasny priklad kdy by pouziti vlakna bylo naprosty nesmysl, uz proto, ze vami popsany program je ryze sekvenci.

Ozval jsem se, nebot autor zacne relativne brzy s vlakny a vubec se zatim nemluvilo o tom, co je skutecne bezne potreba.

No, to je zase otazka na autora, ale vice co? On mozna chtel ukazat, jak snadne pouziti vlaken v Qt ve skutecnosti je. V teto diskuzi jsem si od nekolika lidi precetl, jaky hrozne pouziti vice vlaken je, jak tomu nikdo nerozumi a jak to nejde udelat bez chyby, ale primo v clanku vam sam autor dokazuje, ze to muze byt i docela trivialni...

 

21.4.2009 10:23 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

> Rozdeleni procesu do vicevlaken vam totiz umozni podstatneji lepe a jemneji clenit procesorovy cas, mene dulezitym a dele trvajicim vecem dat nizsi prioritu a pritom zachovat vysokou reaktivitu GUI.

Opravdu to realne (ne jenom teoreticky) na Linuxu jde? V singlethreadovem programu neni problem mit explicitni schedulovani jednotlivych callbacku a tak docilit pozadovaneho chovani, ale u threadu bych mel obavy, protoze thready (v C v Linuxu) jsou rizene systemovym schedulerem. Pokud bych mel treba UI thread a vypocetni thread, tak bych mel obavy, ze vypocetni thread dostane od scheduleru cele 'schedulerove kvantum' casu (nevim, kolik to muze byt, 20 ms?) a scheduler po tu dobu treba nepreda rizeni UI threadu (na singlecore stroji), i kdyz  ma UI thread vstup. V tomto pripade by to slo resit absolutnima prioritama mezi thready, ale umi tohle Linuxovy scheduler?

Krom toho pri vetsim poctu threadu a silne interthreadove zavislosti vypoctu bych mel obavy z narustu latence resenych uloh, nebot by se celkove reseni jedne ulohy prolozilo hromadou zpozdeni  zpusobenem cekanim na naschedulovani 'navazujicich' threadu.

mirec avatar 21.4.2009 10:43 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Čas 20ms je takmer spôsobí takmer nepozorovateľnú odozvu gui. Myslím, že použitie vlákna je stále lepšie než z výpočtu skákať na spracovanie eventov gui.
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
21.4.2009 14:37 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Pokud máte takové problémy, tak použijte real-time plánovač (nebo procesorovou afinitu) nebo rovnou celý operační systém vyhoďte, když si myslíte, že to dokážete lépe.

21.4.2009 15:03 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Opravdu to jde a nejenom teoreticky. Sam to bezne pouzivam ve svych programech, kde mam nejakou komunikaci-USB,ethernet, seriove porty. Nebo v tom "google earth like" co jsem zminil jinde. Mnohem snadneji tak totiz oddelite tu komunikacni cast programu od GUI. Proste si napiste komunikacni knihovnu, ktera ma v sobe svuj vlastni komunikacni thread a vyvedete si callbacky, kdyz se stane neco, co by melo GUI zpracovat.

Uvedomte si totiz, jak jsou GUI programy stavene. Vetsinou obsahuji hlavni smycku, ktera ceka na zpravy (spi) a probudi se jen tehdy, kdyz nejaka zprava prijde a pak ji obslouzi.

Kdybyste to chtel cpat do hlavniho threadu, jiste by to slo, ale musel byste si v hlavni smycce GUI programu bud periodicky pollovat, zda pro vas neco neprislo, coz je ten nejhorsi pripad, protoze bud budete polovat casto a proces se bude probouzet prilis casto (budete zahlcovat system a vybijet baterku na NB), nebo naopak budete mit hroznou latenci.

A nebo se vami sledovany deskriptor nejak vsunete do hlavni smycky, aby ta cekala krome svych zprav i na udalost na vami dodanem deskriptoru, ale to se obavam ze nebude vubec jednoduche a vetsina vyssich GUI frameworku vam neco takoveho vubec neumozni.

V obou pripadech navic budete muset nejakym zpusobem zajistit to, aby se program vracel do hlavni smycky v nejakych maximalne definovanych intervalech, abyste si zajistil, ze budou prichozi zpravy z vasi komunikace zpracovany vcas. Coz kdyz budete chtit ukladat vysledky zaroven do databaze nemuzte zarucit. No a proc to teda tak hrozne komplikovat? V cem je takovy problem zalozit druhe vlakno a na tyhle problemy se vykaslat? Ono pouziti nejakeho toho mutexu nebo semaforu zas tak hrozne tezky neni a ve skutecnosti je s tim mnohem mene prace nez resit problemy popsane vyse...

A k tomu schedulovani... Pane Zajicku, to nemyslite vazne? Co ctu vase komentare, tak jsem ziskal pocit, ze mate opravdu ohromne znalosti, ale toto? Vy si opravdu myslite, ze kdyz scheduler prepne na proces a venuje mu kvantum 20ms (coz je extremne hodne) a proces je se zpracovanim svych udalosti hotov (tj. zavola nejakou blokujici funkci) treba za 2ms, tak tech 18ms prijde vnivec? Prepnuti kontextu muze byt jednak evokovano timerem v jadre, ale prave take tim, ze proces udela co potreboval a pak zavola treba tu funkci na cekani na zpravy (treba select) a v tu chvili ma moznost scheduler prepnout na uplne jiny proces. Priklad:

Zpracovava se nejaka GUI akce v hlavnim threadu. Scheduler ji pridelil vami zminenych 20ms.

Druhy(komunikacni) thread je zablokovany a ceka na udalost(treba pres select)

Mezitim prijdou na socket nejaka data.

Hlavni thread dokoncil co delal za 2ms, zavoval ProcessMessages(pravdepodobne nejaky select)

Rizeni je predano jadru a scheduleru, scheduler zjisti, ze zablokovany druhy thread muze bezet, proto na nej prepina.

Druhy thread se rozbiha, udela co ma za treba 2ms se zase uspi (select). Pokud by zpracovani trvalo dele, muze dojit k prepnuti prave timerem. Coz je ale nepravdepodobne.

Scheduler predava rizeni treba uplne jinemu procesu.

Tak kdepak mate tu 20ms latenci? Naopak, tento pristup vam (zejmena v GUI programu) zaruci velmi velmi nizkou latenci. A samozrejme to s nimi nesmite prehanet, v obycejnem GUI programu jsou ospravedlnitelna tak jedna dve vedlejsi vlakna. Ve svem googl-earth-like programu(popsano jinde v tomto vlakne) mam tri- hlavni, ktere dela veskery user interface a 3d rendering, druhe, ktere nacita data z disku a treti, ktere ta data dekomprimuje. Jak uz jsem psal, i na jednoprocesorovem systemu ohromnym zpusobem snizite latenci na panning a zooming map. to cteni dat z disku. Trva dlouho, seek to dokaze hodne protahnout, ale ve skutecnosti se procesor flaka. Proc? No protoze naprogramuje radic disku, DMA a jen ceka na preruseni, kdy mu radic rekne, ze data byla nactena. A proc tento cas nevyuzit k dekompresi dat nactenych drive a jejich zobrazeni? Jiste, muzete pouzit aio, ale tohle je univerzalnejsi, protoze na jinych platformach aio mit nemusite. A ve skutecnosti je to i snazsi.

A co tento pristup udela na viceprocesorovem snad popisovat nemusim. Tak proc ta silena averze vuci vlaknum?

 

 

 

21.4.2009 17:59 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

> A nebo se vami sledovany deskriptor nejak vsunete do hlavni smycky, aby ta cekala krome svych zprav i na udalost na vami dodanem deskriptoru, ale to se obavam ze nebude vubec jednoduche a vetsina vyssich GUI frameworku vam neco takoveho vubec neumozni.

Todle je, AFAIK, standardni postup - vsechny filedescriptory, na kterych program ceka, se obsluhuji z jedne hlavni smycky a z jednoho volani poll (nebo select). GTK to bezne umoznuje a predpokladam, ze ostatni toolkity take. Ciste vypocetni zalezitosti se pousti z idle-handleru. I serverove programy jsou tak casto napsane (pokud nejsou forkujici, nebo multithreadove). Je pravda, ze pro dosazeni nizke latence je treba, aby kazda obsluha sama o sobe netrvala prilis dlouho a to muze kod v nekterych pripadech zkomplikovat.

> Vy si opravdu myslite, ze kdyz scheduler prepne na proces a venuje mu kvantum 20ms (coz je extremne hodne) a proces je se zpracovanim svych udalosti hotov (tj. zavola nejakou blokujici funkci) treba za 2ms, tak tech 18ms prijde vnivec?

Nemyslim, to jsem byl spatne pochopen. Priklad je takovy, ze se provadi nejaky vypocet a behem toho prijde udalost od uzivatele, ktera by mela byt rychle obslouzena. Reseni s vlakny vypada tak, ze vypocetni vlakno je naschedulovano a pokud neni preruseno nebo nedobehne, tak pobezu po cele kvantum a az teprve pote je naschedulovan GUI thread, ktery obslouzi udalost.

Singlethreadove reseni je takove, ze se pouzije poll (select) v kombinaci se SIGIO. Vypocet probiha a v bodech, kde by ho bylo mozne prerusit, kontroluje promennou signalizujici, zda neni neco na vstupu. Kdyz prijde neco na vstup, jadro posle procesu SIGIO, handler updatuje promennou a bezici vypocet se v nejblizsim bode preruseni prerusi a navrati do hlavni smycky, kde se zavola poll a uzivatelska udalost se obslouzi. A tuhle magii se SIGIO a poll samozrejme dela toolkit.

Osobne si myslim, ze pro bezne GUI aplikace je callbackovy zpusob mnohem jednodussi na psani a jeste jednodussi by bylo pouziti korutin a kooperativniho multitaskingu, kdyby to nejaky mainstreamovy jazyk snadno nabizel.

Je pravda, ze tohle reseni neni vsespasne. Thready vedou ve dvou vecech - jednak umozni vyuziti vice jader a jednak Linux ma v mnoha ohledech prisernou podporu asynchronnich operaci. A je take pravda, ze konzervativni pouziti threadu (jake zminujes v tvem mapovem programu) muze byt rozumne (*). Hloupe je, kdyz nekdo pouziva spoustu threadu pouziva jako nahradu za poll (select).

(*) Osobne bych i v tomto pripade spis nez thready pouzil oddelene procesy komunikujici pres sdilenou pamet. Takove reseni ma dve vyhody - jednak je tam ochrana pameti a tedy se snaz lokalizuji pripadne chyby typu prepisovani nahodne pameti, jednak pri pouziti externich knihoven (napr toolkitu v GUI procesu a obrazkove knihovny v dekompresnim procesu) nehrozi, ze ty knihovny pouziji nejake thread-unsafe funkce spolecne pouzivanych knihoven (treba glibc)

21.4.2009 18:56 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

"Todle je, AFAIK, standardni postup - vsechny filedescriptory, na kterych program ceka, se obsluhuji z jedne hlavni smycky a z jednoho volani poll (nebo select. GTK to bezne umoznuje a predpokladam, ze ostatni toolkity take."

Zrovna v GTK ano(a je to asi jediny toolkit, co vim, ze to tam ma), ale napr. wxWidgets vam to uz nedovoli (i kdyz bezi nad GTK). A rekl bych, ze zrovna Qt take ne (ale do detailu ji neznam). Ve windows to take neudelate. Takze jsme u toho, co jsem psal. V GTK to udelate, vsude jinde budete mit problem. Proto si stojim za tim, ze pouziti druheho threadu je reseni univerzalnejsi a tim padem i snadnejsi. Zvlast kdyz pisete portovatelnou aplikaci (zejmena do windows).

"Je pravda, ze pro dosazeni nizke latence je treba, aby kazda obsluha sama o sobe netrvala prilis dlouho a to muze kod v nekterych pripadech zkomplikovat."

Prave, zase mate neco, na co musite zbytecne myslet. Coz vam zase o trochu snizuje univerzalnost reseni.

"Nemyslim, to jsem byl spatne pochopen"

Omlouvam se, divil jsem se, ze clovek vasich znalosti by nevel toto..

"Kdyz prijde neco na vstup, jadro posle procesu SIGIO, handler updatuje promennou a bezici vypocet se v nejblizsim bode preruseni prerusi"

No dobre, ale ten test musite udelat v te vypocetni rutine. A timto do ni budete zatahovat balast, ktery tam vlastne nepatri. Proc si do ciste matematicke rutiny, ktera pocita dejme tomu 2D FFT a chcete ji mit i portovanou do nejakeho embedded zatahovat neco, co vyuzijete na uplne jine platforme? Navic, ve Windows nic takove neni, wxWidgets a pravdepodobne ani Qt vam zadny handler k SIGIO neda (protoze to neni portovatelny zpusob).

A navic, nemate pravdu. Kdyz prijdou nejaka data, beztak jsou nejprve zpracovana v jadre (je vyovlano IRQ). Tzn. je skoceno do jadra a je zavolan scheduler. Pokud date komunikacnimu vlaknu patricne vyssi prioritu (pres setpriority), dojde po zpracovani dat ke switchi prave do komunikacniho vlakna a ne zpet do vypocetniho. Takze vas argument o latenci mluvi spis proti.

Nezlobte se, ale prijde mi, ze vsechny vase navrhy, jak se vyhnout threadum vedou pouze k zapleveleni kodu a hlavne k znemozneni psani platforme nezavisleho kodu. A porad nechapu proc. Proc se za kazdou cenu vyhybat necemu, co existuje na temer vsech platformach (v RTOS je to primo podstat programovani) a umozni vam psat cistsi kod.

"Hloupe je, kdyz nekdo pouziva spoustu threadu pouziva jako nahradu za poll (select)."

Zde se uprimne priznam k neznalosti. Jak tedy mam udelat server, ktery (kvuli portabilite) nema pouzivat fork a bude treba cist/zapisovat na disk? Vzdyt pokud bych ho udelal jednovlaknove, staci aby jeden klient vyzadoval pristup na disk, ktery je v linuxu blokujici (neuvazuji aio) a ostatni klienti maji po dobu cekani na data smulu... Ja bych to opravdu resil metodou thread per connection. Jake je jine reseni?

"Osobne bych i v tomto pripade spis nez thready pouzil oddelene procesy komunikujici pres sdilenou pamet."

Tak ja uz opravdu v tomto pripade nevidim prilis rozdil v tom, jestli si vytvorim vice vlaken nebo si nasdilim hodne pameti mezi procesy.  Krome toho, ze reseni s procesy zase nenaportuji na windows. A zde se vas znovu zeptam (nemam tuto znalost), jak se v posixu sdili synchronizacni objekty mezi procesy? Nejakym zpusobem musim dat vedet druhym procesum, ze maji neco delat nebo ze neco bylo udelano. Co vim, tak posix neumoznuje sdilet mutexy a semafory, snad jen delat to pres pipe. Nikdy jsem to nezjistoval, protoze me se naopak zda, ze odladit jeden vicevlaknovy program je snadnejsi, nez resit meziprocesovou komunikaci mezi vice procesy. Ale to je muj subjektivni nazor. Ja s vlakny pracovat musim, pri programovani RTOS ani jinou moznost nemate a tak me to jako takove peklo neprijde. Spis naopak. Ale stejne tu averzi vuci vlaknum nechapu. I kdyz vami uvadeny argument o pouziti thread unsafe knihoven je urcite platny.

 

 

 

 

 

 

 

21.4.2009 22:15 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
+1

Podle mě k psaní vícevláknové aplikace je nejdřív nutné pochopit problematiku vláken - atomické operace, zámky, synchronizační mechanismy, a vlákna samotné. Kód je přesně jak píšete - čistčí a více přenositelný.
22.4.2009 00:44 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

> Zvlast kdyz pisete portovatelnou aplikaci (zejmena do windows)

Ono psat psat program portovatelny mezi Windows a Linuxem je samo o sobe dost posetile :–).

> Pokud date komunikacnimu vlaknu patricne vyssi prioritu (pres setpriority), dojde po zpracovani dat ke switchi prave do komunikacniho vlakna a ne zpet do vypocetniho. Takze vas argument o latenci mluvi spis proti.

To je pravda, nicmene setpriority() pro to neni moc vhodna - uz treba jen proto, ze komunikacni vlakno uzivatelskeho programu si jim prioritu zvysit nemuze, akorat ostatni vlakna si muzou prioritu snizit, ale tim si snizi prioritu i vuci ostatnim programum. A krom toho se jedna jen o relativni prioritu, takze mozna ani k predani rizeni nedojde. IMHO by to chtelo vic moznosti pro program k ovlivneni schedulovani svych threadu - napr. moznost ridit schedulovani threadu v ramci procesu pomoci absolutnich priorit jednotivych threadu (coz lze snadno delat v event-based modelu), ci moznost synchronniho predavani rizeni mezi thready.

> Zde se uprimne priznam k neznalosti. Jak tedy mam udelat server, ktery (kvuli portabilite) nema pouzivat fork a bude treba cist/zapisovat na disk? Vzdyt pokud bych ho udelal jednovlaknove, staci aby jeden klient vyzadoval pristup na disk, ktery je v linuxu blokujici (neuvazuji aio) a ostatni klienti maji po dobu cekani na data smulu...

Spatne. V Linuxu podpora pro rozumne AIO (ktere by snadno resilo) prakticky neexistuje (a glibc POSIXove AIO emuluje pomoci vlaken). Na druhou stranu je otazka, v kterych pripadech je to opravdu nutne a prinese to nezanedbatelne zlepseni.

Mozne reseni je treba mit par vlaken/procesu (radove tolik, kolik mas jader) a v kazdem mit. normalni event loop pro vyrizovani pozadavku. Tim se jednak vyuziji vsechna jadra procesoru a jednak je jen male riziko, ze budou procesory cekat, protoze vsechny instance budou cekat na disk.

> A zde se vas znovu zeptam (nemam tuto znalost), jak se v posixu sdili synchronizacni objekty mezi procesy?

System V IPC nabizi semafory a message queues.

22.4.2009 11:06 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

"IMHO by to chtelo vic moznosti pro program k ovlivneni schedulovani svych threadu - napr. moznost ridit schedulovani threadu v ramci procesu pomoci absolutnich priorit jednotivych threadu"

Priznam se, ze detailni znalost toho, jak toto funguje na Linuxu nemam (uz proto, ze tech scheduleru v jadre je cela rada), ale kazdy RT OS by to udelal presne jak jsem popisoval. Resit jsem to nemusel, protoze jak uz tady nekdo psal, i tech teoretickych 20ms ve vetsine GUI aplikaci nepredstavuje problem. Ale prinutil jste me trosku hledat a po projiti pthread.h a sched.h jsem nasel funkce, o ktere jsem nevedel - sched_setscheduler, resp. pthread_setschedparam (ta druha vyuziva tu prvni), ktera prave umoznuje nastavovat vami popsanou priorizaci vlaken uvnitr procesu a danym vlaknut dat RT prioritu(tzn. melo by to zajistit mnou popsane chovani). Ale jak rikam, praktickou zkusennost na Linuxu s tim nemam.

"Na druhou stranu je otazka, v kterych pripadech je to opravdu nutne a prinese to nezanedbatelne zlepseni."

No, tak prinese to zlepseni vsude tam, kde chci napsat server, kde klienti napr. pristupuji na disk. Souborove operace na Linuxu jsou blokujici, tudiz kdyz hlavni smycka "zamrzne" v nejakem souborovem IO, ostatni klienti (bez pozadavku na file IO maji smulu), ale pritom by mohli byt obslouzeni, protoze se procesor vlastne flaka v jadre a ceka, az mu radic doda data. Aby k tomu nedoslo, vyresite to prave vlastnim threadem po kazdeho klienta nebo forkem. Fork jsem zavrhl kvuli portabilite, tak zbyva reseni thread per connection. A v cem je vlastne rozdil? S NPTL je reseni s thready urcite stejne rychle, mozna i rychlejsi (protoze pri prepinani  se nemusi delat context switch pametoveho prostoru, ale to jenom hadam) nez pres procesy. Tak kde je vyhoda forkovani? Argument o tom, ze pri padu procesu spadne jenom dane spojeni, ktere chybu zpusobilo beru, ale jen z casti, protoze je to jen volba mezi dvema zly a v dusledku je pad spojenii stejne neprijatelny jako pad serveru a v obou pripadech musite zacit s debugovanim.

"Mozne reseni je treba mit par vlaken/procesu (radove tolik, kolik mas jader) a v kazdem mit. normalni event loop pro vyrizovani pozadavku."

Tak tohle jsem nepochopil. Co to vyresi? Vzdy ten samy vyse popsany problem prece zustane,ne? Budete mit dve jadra(A a B), dva thready a treba ctyri klientska spojeni (1,2,3,4). 1 a 2 na jadre A a 3 a 4 na jadre B. Pokud si spojeni 1 vyzada file IO, po dobu jeho vyrizeni ma spojeni 2 smulu. Sice tim problem zmirnite (spojeni 3 a 4 budou obslouzena), ale reseni s nejvetsi propustnosti je proste jeden thread na jedno spojeni. Nehlede na to, ze rozhodne bude jednodussi napsat program, ktery ma X threadu na X spojeni, nez program, ktery ma X threadu na Y spojeni,ne?

"System V IPC nabizi semafory a message queues."

Hmm, a opravdu si myslite, ze synchronizace pres IPC mezi procesy je rychlejsi nez pres mutexy a semafory v ramci jednoho procesu? Jako ja to nevim, ale dovolim si o tom pochybovat.

"Ono psat psat program portovatelny mezi Windows a Linuxem je samo o sobe dost posetile :–)."

No jo no, kdyz to vidite takhle... Ja to zas vidim tak, ze kdyz muzu napsat program prenositelneji (a pritom si dokonce usetrim praci), tak to tak udelam. A uz jsem nekolik takovych programu napsal, posetile me to neprijde, prave naopak. A jsem rad, ze stale vic dodavetelu softwaru vas nazor nesdili a ja napr. kvuli navrhu logiky pro Xilinx nemusim pouste Windowsy (mimochodem take diky Qt)...

Je ovsem zajimave, ze jsem od vas neslysel zadny skutecny argument, proc se vlaknum branit. V podstate jsem se jenom dozvedel navrhy jak to delat jinak (o jejichz univerzalni pouzitelnosti a nejakem vykonovem prinosu si dovoluji pochybovat), ale porad nevim proc. Neni tvrzeni "VLAKNA JSOU ZLO" jenom takove hloupe a prezite unixove paradigma?

 

 

 

 

22.4.2009 11:35 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Souborove operace na Linuxu jsou blokujici

Já vám nevím, ale manuály a moje praxe ohledně fd = open(filename, O_NONBLOCK) ve spojení se select(2)/poll(2) tvrdí něco jiného.

22.4.2009 11:52 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

A proc by teda nekdo vymyslel aio, kdyz by fungovalo tohle? ;-)

Prave v manualu se pise "When possible, the file is opened in non-blocking mode". Co aspon ja vim, neblokujici souborove operace fungovaly pouze pro pipy, ne pro skutecne soubory. Zmenilo se neco?

22.4.2009 13:55 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
A proc by teda nekdo vymyslel aio, kdyz by fungovalo tohle?

Protože AIO je jiný koncept než select(2) (AIO je spíš o tom, jak naložit práci jádru, sám si dělat něco jiného a pak dostat od jádra signál, že práce je hotová). V POSIXu máte spoustu různých nástrojů, jak dosáhnout téhož.

neblokujici souborove operace fungovaly pouze pro pipy

To je možné, že to tak bylo, ale z praxe můžu říct, že to funguje i na souborech nebo TCP socketech. Dokonce v select(2) se píše:

Under Linux, select() may report a socket file descriptor as "ready for
reading", while nevertheless a subsequent read blocks.  This could  for
example  happen  when  data  has arrived but upon examination has wrong
checksum and is discarded.  There may be other circumstances in which a
file  descriptor is spuriously reported as ready.  Thus it may be safer
to use O_NONBLOCK on sockets that should not block.
22.4.2009 14:19 masi
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Obavam se, ze se mylite. Neblokujici zapis do SKUTECNEHO souboru vam pres O_NONBLOCK proste nebude fungovat. Vychazi to z toho, ze soubory nemaji pridelen zadny FIFO buffer, kam by se data vlozila pred tim, nez budou  zapsana. A bude se to chovat tak, ze select, kteremu podstrcite filedeskriptor skutecneho souboru vam nikdy nevrati, protoze zapis do takoveho souboru bude vzdy blokujici.

"Dokonce v select(2) se píše:"

A co to s tim souvisi? Vzdyt to je jen citat z manualu k selectu. Ale nerika to nic o tom, jak se to bude chovat na skutecny soubor. 

Jiste select/poll vam bude fungovat prave na TCP sockety (coz je jeho primarni ucel), stejne tak jako na FIFO roury - proto si mozna myslite, ze to funguje na soubory, ale /dev/ttyS0 neni ve skutecnosti soubor, ale pojmenovana FIFO roura. Na skutecny fyzicky soubor na disku vam tento pristup fungovat nebude. Proto bylo navrzeno aio.

22.4.2009 15:17 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

> /dev/ttyS0 neni ve skutecnosti soubor, ale pojmenovana FIFO roura.

/dev/ttyS0 neni pojmenovana FIFO routa, ale device node, coz ale na veci nic nemeni.

22.4.2009 16:57 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Máte pravdu. Neblokující zápis do souboru neřeší, jestli se podaří zapsat data okamžitě, nebo se budou zapisovat hlemýždím tempem.
22.4.2009 15:15 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

> Já vám nevím, ale manuály a moje praxe ohledně fd = open(filename, O_NONBLOCK)

To na bezne soubory opravdu nefunguje tak, jak by to bylo potreba por asynchronni provoz.

22.4.2009 16:06 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

> Priznam se, ze detailni znalost toho, jak toto funguje na Linuxu nemam (uz proto, ze tech scheduleru v jadre je cela rada), ale kazdy RT OS by to udelal presne jak jsem popisoval.

setpriority() nastavuje jen jakesi relativni vahy (alespon pro normalni procesy se schedulovaci policy SCHED_OTHER). Je mozne nastavit jinou schedulovaci policy s real-time prioritama (pomoci sched_setscheduler() a thread_setschedparam()), ale to neni reseni pro uzivatelske programy, nebot to potrebuje prava roota.

> No, tak prinese to zlepseni vsude tam, kde chci napsat server, kde klienti napr. pristupuji na disk

Jo, to je jasne, jenom si nemyslim, ze ve vetsine pripadu ten zisk bude nejak signifikantni, treba z hlediska celkove propustnosti serveru. Ale to je asi vec pripad od pripadu jina.

> Hmm, a opravdu si myslite, ze synchronizace pres IPC mezi procesy je rychlejsi nez pres mutexy a semafory v ramci jednoho procesu?

Nevim jak je to presne implementovane, ale nevidim duvod, proc by semafory mezi thready mely by implementovane jinak nez semafory mezi procesy. V podstate vzdy potrebuji akorat kus sdilene pameti a moznost se uspat. To, zda se k nim pristupuje pres system V IPC rozhrani nebo pres pthread rozhrani, uz je jen detail.

 

> Je ovsem zajimave, ze jsem od vas neslysel zadny skutecny argument, proc se vlaknum branit. V podstate jsem se jenom dozvedel navrhy jak to delat jinak (o jejichz univerzalni pouzitelnosti a nejakem vykonovem prinosu si dovoluji pochybovat), ale porad nevim proc. Neni tvrzeni "VLAKNA JSOU ZLO" jenom takove hloupe a prezite unixove paradigma?

No ja tady taky nikde netvrdil, ze 'vlakna jsou zlo', tak nevidim, proc bych mel prinaset argumenty proc se vlaknum branit :–) Ale kdyz uz jsem byl ptan:

Jedna oblast namitek vychazi z toho, ze obecne mam neduveru k postupum, ktere pri drobne chybe vedou k plizivemu poskozeni datovych struktur (a navic jen s malou pravdepodobnosti), proto bych thready pouzival jen konzervativne. A pri takovem konzervativnim pouziti (kde jsou jasne oddelene ucely jednotlivych threadu a je mezi nima jasne komunikacni rozhrani, treba nejaky ring buffer nebo fifo roura, a nesdili se moc pameti) je otazka, zda uz neni rovnou lepsi pouzit oddelene procesy a ziskat navic dalsi vrstvu ochrany a nemit problemy s thread-unsafe knihovnama.

Druha oblast namitek vychazi z toho, ze si myslim, ze Linuxovy scheduler prilis nepocita s tim, ze mezi tasky budou vyznamne zavislosti a nenabizi proto dost prostredku pro podporu takove situace. Staci se podivat na LKML do diskusi, kdyz se menil scheduler, na to, jak ruzne zmeny v scheduleru ovlivnovaly latenci a vykon Xovych programu, a to jde jen o jednoduchou komunikaci typu program - X server. V pripade event-driven programu ma programator plnou kontrolu nad tim, v jakem poradi se spusti jednotlive callbacky.

 

20.4.2009 16:54 Bubak
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Hehe, takhle jsem se nepobavil hodne dlouho.

Takze delam GUI, pokazde kdyz neco taham z DB, lezu na disk tak to delam v jinem threadu. Taky kazdy trochu vetsi cyklus delam paralelni.

Je to otazka peti pismen a dvou zavorek navic. Ale nedelam v C++. :-)
20.4.2009 21:17 dad
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

A nemohl by jste vysvetlit, proc to delate?

Abychom se zasmali zase my ostatni.

21.4.2009 10:34 Bubak
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Protoze je program rychlejsi?!
mirec avatar 20.4.2009 08:34 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Qt Concurrent
Celkom by ma potešil diel o Qt Concurrent. Plánuje sa niečo také?
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
David Watzke avatar 20.4.2009 15:16 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Qt Concurrent
Zatím o tom vím jen že to existuje, takže vyloženě v plánu to není, ale když se s tím časem naučím, tak určitě. Jinak kdyby se tu našel někdo, kdo by o tom chtěl napsat, tak je vítán, normálně ten díl zařadíme do seriálu. Plánuju taky vytvořit další seriál o Qt, ale soustředěnej spíš na non-GUI věci. Qt má totiž spoustu věcí, který se dají předvádět v GUI, ale fungují i bez něj. Takže teď se (v tomhle seriálu) vždycky snažím v každé ukázce předvést hned několik nových věcí najednou. Ten druhej seriál by se pokaždý zabýval něčím jiným, takže by tam bylo víc místa pro nový věci, místo toho abych k tomu pořád vytvářel GUI. To se bude hodit hlavně až ty ukázky začnou být trochu složitější a navíc v tomto seriálu zbyde víc místa pro čistě GUI záležitosti :-)
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
mirec avatar 20.4.2009 16:15 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent

Qt Concurrent je skvelá vec na na paralelné spracovanie dát. Veľmi jednoduchým spôsobom sa tam dajú urobiť veci ako hromadné resizovanie obrázkv pričom počet vlákien sa nastaví automaticky. Qt Concurrent predstavuje spôsob vytvorenia multithreadovej aplikácie bez nutnosti používania synchronizačných primitív. Stačí spustiť cez concurrent a cez watcher odchytiť signal emitovaný pri dokončení úlohy. Ten Concurrent ma napadol len tak pri vláknach, Qt má viacej zaujímavých vlastností o ktorých by sa oplatilo napísať .. ale to by bolo asi na trochu dlhší a rozsiahlejší seriál. Keď by som ešte k tomu rátal Qt Jambi (s ktorým sa práve trápim), veci, ktoré ešte v Qt nie sú (Kinetic - pohybový senzor, kopírujeme rozhranie iphonu a ďalšie kraviny) tak by to bolo fakt na poriadne rozsiahly seriál.

Ja žiaľ nemám čas ani schopnosti na napísanie článku, ale strášne rád skúšam nové veci, takže možno o tom napíšem drobný blog ;)

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
David Watzke avatar 20.4.2009 16:22 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Qt Concurrent
Qt má viacej zaujímavých vlastností o ktorých by sa oplatilo napísať .. ale to by bolo asi na trochu dlhší a rozsiahlejší seriál.
Delší a rozsáhlejší než...? Já ještě nekončím :-)
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
mirec avatar 20.4.2009 16:43 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent
No je fakt, že to neviem, len tak usudzujem podľa tempa. Pri týchto vychytávkach by trebalo ísť dosť do hĺbky. Ale zasa je fakt, že na začiatok tieto podrobnosti netreba a dá sa k nim vrátiť. Ak bude tento seriál poriadne dlhý budem len rád ;)
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
David Watzke avatar 20.4.2009 16:51 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Qt Concurrent
Klidně můžeš navrhnout konkrétní věci (třeba mi napiš mail) a já z toho pak třeba něco vyberu.
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
20.4.2009 17:12 kapo | skóre: 15 | blog: runtime
Rozbalit Rozbalit vše Re: Qt Concurrent

Ahoj,

  uz pres rok se taky s Qt Jambi trapim, tak kdybys mel nejakej zapeklitej problem, tak se mi klidne ozvi, treba to uz mam vyreseny :).

K.

Why make things difficult, when it is possible to make them cryptic... - Aksel Peter Jorgensen
mirec avatar 20.4.2009 17:53 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent
Příloha:
Ďakujem za ponuku. Ja sa s Qt Jambi trápim už asi 2 dni, zatiaľ mám pár tisíc riadkov kódu, ešte tak okolo 1000 a mám s Qt Jambi pokoj (jej to len semestrálka, využívam z Qt minimum, kúsok QtCore, QtSql a QtGui. Aby bolo jasné čo asi robím tak posielam screenshot, je to dokopy nič.
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
20.4.2009 18:02 kapo | skóre: 15 | blog: runtime
Rozbalit Rozbalit vše Re: Qt Concurrent

Tak to ta moje potvora vypada trochu sloziteji, ale v podstate vyuzivam ty same komponenty jako ty. Proste databazova GUI aplikace, ktera ma i nejake custom widgety pro kresleni takovych specifickych tabulek :)

 

Why make things difficult, when it is possible to make them cryptic... - Aksel Peter Jorgensen
mirec avatar 20.4.2009 18:12 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent
Eh ja zásadne pre kreslenie tabuliek využívam ANSI/VT100 sekvencie nech je sranda ;) Ale tie custom widgety to som nemal čítať .. normálne mám chuť si jeden napísať (síce nie na tento projekt ale aj tak). No tak to vidím, že dnes to asi nedokončím a pustím sa do písania jedného zložitejšieho widgetu (canvas a tak ...).
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
20.4.2009 18:24 kapo | skóre: 15 | blog: runtime
Rozbalit Rozbalit vše Re: Qt Concurrent

No asi jsem to blbe vyjadril. Ja to vlastne nedelam jako custom widget, ale jako qgraphicscene zobrazovany pres qgraphicsview. Jeden je jen pro zobrazovani (ale je to velky, tak potrebuju zvetsovat a posouvat) a druhy bude interaktivni.

QTableView je dost pomalej pro zobraeni vice dat (hint: zkus si udelat normalne model->view vlastni model treba pro 500x500 prvku, kazdej 20x20px a s jinou barvou pozadi a pak si ten view roztahni na celou obrazovku. Scrollovani a vyber je strasne zdechlej).

Why make things difficult, when it is possible to make them cryptic... - Aksel Peter Jorgensen
mirec avatar 20.4.2009 19:04 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent
Příloha:
Tak som si pre istotu urobil 20000 x 500. Asi máme trochu iný hardware pretože u mňa to ide absolútne plynulo (niekto mi už aj hovoril, že ne mojom stroji ide Qt 4 bleskovo, takže som možno výnimka). V prílohe je môj kód.
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
21.4.2009 08:24 kapo | skóre: 15 | blog: runtime
Rozbalit Rozbalit vše Re: Qt Concurrent

hmm, mozna jsme si nerozumeli, ale ja se bavim o QT Jambi. Tohle je ciste Qt vec. Tam verim, ze to bude rychle. U tak velkych tabulek tam lita strasne moc signalu (radove 10 000) mezi Javou a Qt knihovnou a to je asi duvodem toho, ze to je tak zdechly. Jo a ten muj prg. Je poustenej pod widlema, mozna to taky neco ovlivnuje.

A jeste: to mas zkouseny na Qt 4.5? Nebo na 4.4. Protoze Qt Jambi jeste na 4.5 neni (je jen preview).

Why make things difficult, when it is possible to make them cryptic... - Aksel Peter Jorgensen
mirec avatar 21.4.2009 08:48 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent
Používam Qt 4.5.0 a Qt Jambi 4.5.0_rc1. Medzi 4.4 a 4.5 pribudlo dosť veľa optimalizácii, takže je to možno spôsobené aj tým.
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
21.4.2009 10:03 kapo | skóre: 15 | blog: runtime
Rozbalit Rozbalit vše Re: Qt Concurrent

hmm to zni zajimave :) ale ten tvuj priklad je stejne pure QT. Zkus ho prepsat do javy a uvidis, jestli se to bude chovat stejne.

to qtjambi jsi genroval sam nebo to mas dodane v distribuci?

 

Why make things difficult, when it is possible to make them cryptic... - Aksel Peter Jorgensen
mirec avatar 21.4.2009 10:13 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Qt Concurrent
Našťastie v distribúcii, ručne skompilovať mi to nešlo (a to mám gentoo, takže to si skompilovalo samo i keď netuším ako je možné, že úspešne).
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
20.4.2009 16:37 Murry | skóre: 16 | Brno
Rozbalit Rozbalit vše Re: Qt Concurrent
Toto tema by me take zajimalo. Moc zajimalo....
Je to zpusob jak si ulehcit praci a chybovost, ale u me to zatim vedlo k opaku..coz je smutne:(
Jardík avatar 20.4.2009 10:56 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
int step = file->size() / 100;
Hádej co se mi nelíbí? :-)
Věřím v jednoho Boha.
mirec avatar 20.4.2009 11:18 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Hmm, žeby:
int step = file->size() / 0x64;
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
20.4.2009 12:58 Michal Vyskočil | skóre: 60 | blog: miblog | Praha
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Jardovi jde spíš o
site_t step = ...
i když jak se dívám do dokumentace, tak tam patří spíše qint64.
When your hammer is C++, everything begins to look like a thumb.
20.4.2009 12:59 Michal Vyskočil | skóre: 60 | blog: miblog | Praha
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
*size_t
When your hammer is C++, everything begins to look like a thumb.
20.4.2009 13:46 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
size_t určitě ne, int64_t jo
Jardík avatar 20.4.2009 17:21 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Alespoň někdo přemýšlí :-) Nikde totiž není zaručeno, že 64bit číslo (např. 0x7FFFFFFFFFFFFFFF) děleno stem se vejde do 32bit integeru. Je sice hezké předpokládat, že tak velký soubor nebude... ale příklad. Pracuji s pevným diskem přes soubor zařízení, který má 2TB, jak bude velký "step"? Nevejde, co? :-)
Věřím v jednoho Boha.
David Watzke avatar 20.4.2009 15:26 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Díky, opraveno...
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
Jardík avatar 20.4.2009 17:22 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
To je dobře, alespoň mám klid v duši :-)
Věřím v jednoho Boha.
20.4.2009 20:58 Luboš Luňák | skóre: 19 | blog: Seli
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Asi ne. Ještě je tam případné dělení nulou >:).
Jardík avatar 20.4.2009 23:20 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
:-)
Věřím v jednoho Boha.
20.4.2009 11:16 T.O.M. | skóre: 22 | blog: T.O.M.'s blog | Ostrava
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

THUMBUP, necekane jsi me dostal - o pristupu k standardnim ikonam systemu jsem vazne nevedel (a to byl pridan uz ve verzi 4.1)
Hned vecer zacnu upravovat sve aplikace :-)

msk avatar 28.4.2009 10:18 msk | skóre: 27 | blog: msk
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
O com hovorime, nech sa priucim?
28.4.2009 11:22 T.O.M. | skóre: 22 | blog: T.O.M.'s blog | Ostrava
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

"o pristupu k standardnim ikonam systemu"?

msk avatar 28.4.2009 11:58 msk | skóre: 27 | blog: msk
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
:-) Ja som skor cakal odpoved v style "... hovorime o QStandardSystemIcons, si slepy ty pako?", pretoze v kodoch clanku nic s ikonami nevidim a sameho ma to tiez zaujima, pretoze by som aj ja rad zacal upravovat svoje aplikacie :-)
28.4.2009 12:34 T.O.M. | skóre: 22 | blog: T.O.M.'s blog | Ostrava
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Ok, neni na to zadna spec. trida. Kazdy widget ma metodu style(), ktera vraci ukazatel na QStyle. Pak uz je jen na tobe, co kazdemu widgetu nastavis. V druhem prikladu clanku je uvedena jedna z moznosti, tedy pouziti standardni ikony. Jejich vycet najdes pod QStyle::StandardPixmap, napr.:

nejakyUkazatelNaWidget->style()->standardIcon(QStyle::SP_TrashIcon);
Pokud potrebujes spis QPixmap nez QIcon (treba pro QLabel), musis sam provest konverzi viz. druhy priklad v clanku...

msk avatar 28.4.2009 13:12 msk | skóre: 27 | blog: msk
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Ahaaa, diky moc, na to sa pozriem.
28.4.2009 13:57 T.O.M. | skóre: 22 | blog: T.O.M.'s blog | Ostrava
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Samozrejme priklad, co jsem uvedl nic nenastavuje, ale pouze vrati vybranou std. ikonu jako QIcon objekt pro styl pouzity u nejakyUkazatelNaWidget. Prizadit ji jinemu widgetu uz je na tobe. (To jen pro pripad, ze chtel nekdo zacit rypat ;-) )

20.4.2009 16:55 Karell
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Přestože se může zdát jednodušší přistupovat z vlákna ke grafickému rozhraní přímo (například přes předaný ukazatel), vhodnějším řešením je vysílat z vlákna signály, na které bude GUI reagovat. Kód je pak univerzálnější a navíc si tak jasně oddělíme GUI od zbytku programu.

Mate pravdu, ze je to vhodnejsi reseni, ale myslim, ze by se sluselo rict, ze se to tak delat dokonce musi. Do GUI muze pristupovat jen hlavni thread a zadny jiny. Je to tak bezne ve vetsine GUI knihovnach a obavam se, ze to malo kdo vi a dodrzuje. Ono se to totiz vetsinou neprojevi a tak programator ani nevi, ze dela neco spatne.

mirec avatar 20.4.2009 17:03 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Nepoznám nikoho kto by to v Qt nedodržiaval. Ale je to možné tým, že signály a sloty sú tak pohodlné, že väčšinu ľudí ani nenapadlo použiť niečo iné. Mimochodom v dokumentácii ku Qt do dosť zdôrazňujú, že nešahať z iných vlákien ;)
LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
20.4.2009 17:11 kapo | skóre: 15 | blog: runtime
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

no v qt jambi to na korektni vlakno testuje u kazdeho volani QT funkce, takze to zkusite jednou a hned to vychcipa :)

 

Why make things difficult, when it is possible to make them cryptic... - Aksel Peter Jorgensen
21.4.2009 12:36 jan.xxx
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)

Chtělo by to dát odkaz na projekt (zazipované zdrojáky). Pak by to mělo nemělo chybu.

David Watzke avatar 21.4.2009 14:48 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
O tom jsem uvažoval už dřív, jenže vzhledem k tomu, že to všechno jsou spíš ukázky než použitelný programy, tak to nemá moc cenu. Pro mě by to nebyl až takovej problém, akorát kdyby se pak našla nějaká chybka, tak bych se s tím musel párat nejen já, ale pak ještě otravovat adminy, aby to nahradili... takže tak. Ještě si to rozmyslím.
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
21.4.2009 22:33 Robert Krátký | skóre: 94 | blog: Robertův bloček
Rozbalit Rozbalit vše Re: Grafické programy v Qt 4 - 5 (regexpy, vlákna a ukazatel průběhu)
Už jsme to tak dělali u jiných článků - není to problém.

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.