Prioritizace vláken v C

Prioritizace vláken v C
« kdy: 17. 08. 2016, 12:45:15 »
Čau ve spolek,
můj dotaz směřuje k vláknu.
Mám vlákno, co mi scanuje v periodě(cca 100ms) nějaký příchozí data, nicméně se mi stává, že data jsou občas přesná a občas přesná nejsou. Napadlo mne vyřešit to prioritou vlákna?? Nicméně s vlákny začínám a docela v tom tápu.
Je to pro linux Debian 7 wheezy.

Tady je kód:

Kód: [Vybrat]
#include <stdio.h>
#include <unistd.h>
#include <cstdint>
#include <thread>
#include <iostream>
#include <iomanip>
#include "boost/date_time/posix_time/posix_time.hpp"

extern "C" {

#include "libico300.h"

}

using namespace std;
using namespace boost::posix_time;

void wait(int milli_seconds) {

this_thread::sleep_for(chrono::milliseconds(milli_seconds));

}

void threadf(int cas) {

int a = 0;


while(true) {

wait(cas);

uint8_t stav;

ICO300_get_DI(&stav);

if (stav != a) {


cout << " VZESTUPNA HRANA " << endl;

}
else {


cout << " SESTUPNA HRANA " << endl;

     }


a = stav;


}

}


int main() {


char c;

ICO300_set_DIO_mode(0xff);
int parametr_cas;

cout << " Zadejte cas v [ms]: " << endl;
cin >> parametr_cas;


thread t{threadf,parametr_cas};

return 0;

}
« Poslední změna: 17. 08. 2016, 14:03:40 od Petr Krčmář »


JSH

Re:Prioritizace vláken v C
« Odpověď #1 kdy: 17. 08. 2016, 15:44:04 »
Ahoj, priorita vláken je dost závislá na plattformě. Můžeš zkusit vevnitř vlákna zavolat pthread_self a získat nativní id pro pthread_setschedprio.

... data jsou občas přesná a občas přesná nejsou.

Co tímhle přesně myslíš? Že to občas čeká dýl než těch 100ms? S tím musíš počítat, protože linux v základu není realtime a odezvu nemáš nijak garantovanou. Priority tomu moc nepomůžou.

Neviditelný

Re:Prioritizace vláken v C
« Odpověď #2 kdy: 17. 08. 2016, 15:45:24 »
Text dotazu mi přijde poněkud zmatený. Domnívám se správně, že potřebuješ, aby se to vlákno probudilo vždy po nějakém čase s co možná nejvyšší přesností, přičemž na té přesnosti závisí správné fungování celého programu? Tenhle problém je totiž v non-realtimových multitaskingových prostředích inherentně neřešitelný tímto způsobem. Mimochodem ten tvůj jednoduchý příklad žádné vlákno ani nepotřebuje.

aaa

Re:Prioritizace vláken v C
« Odpověď #3 kdy: 17. 08. 2016, 22:17:11 »
Spravne riesenie bez realtime systemu neexistuje. Existuje trochu fungujuce riesenie.

Program spustaj cez chrt so spravnymi parametrami, na zaciatku si uloz cas, aby ti to neuchazalo. Od neho pocitaj, kolko cakat. Takto zadas 100ms a kazda iteracia trva naviac mozno 1ms, niekedy aj viac (scheduler), tak po nejakom case mozno nieco preskocis.

A ako pisu ostatni, vlakno na toto nepotrebujes.

JmJ

  • ****
  • 333
    • Zobrazit profil
Re:Prioritizace vláken v C
« Odpověď #4 kdy: 18. 08. 2016, 10:30:32 »
a) priority vlaken bych neresil, to mi v praxi nikdy nefungovalo prilis dobre a hlavne to nikdy nebude presne (jak psali vyse)

b) pokud vam jde o monitorovani cca 100ms pulzu, pak zvyste vzrokovaci frekvenci treba na 10 ms nebo i vic, zalezi, jak presne chcete zmeny chytat.

c) muzete take poresit to, ze provadeni samotne kontroly bere nejaky cas. Hned po spanku si zapamatovat/zacit merit cas a dalsi spanek naplanovat na "standardni delka spanku" - "cas zabrany merenim". Tim se co mozna nejvic priblizite presnemu vzorkovani.

d) jsou veci, ktere v ne-realtime multitaskovem systemu na urovni uzivatelske aplikace proste bezchybne ucasovat nejdou. Musi na ne byt bud driver do jadra os, nebo specialni hw.


PetrM

Re:Prioritizace vláken v C
« Odpověď #5 kdy: 18. 08. 2016, 10:53:25 »
No, pokud bude sedm priorit a standardní čtyřka, tak by priorita 6 fungovala do chvíle, než někdo dá šestku nebo sedmičku do jiné aplikace. Jinak je to v p...

Jedině vyšší vzorkovací frekvence s tím, že delay() zaručuje minimální čas, takže i při nastavení na 10ms to může jet znovu po 150ms. Při požadavku na přesnost řešit na úrovni ovladače nebo železa.

Re:Prioritizace vláken v C
« Odpověď #6 kdy: 19. 08. 2016, 10:35:45 »
Pánové moc děkuji za vyčerpávající odpovědi.
Ale teď mi nejde o přesnost toho vzorkování,  protože jsem se zasekl na de...lním bit shiftu.
Tady je kód a popis chyby.
Přitom scanování to neustále vypisuje 1 a nereaguje na změny stavu jednotlivých pinů. Myslel jsem si, že by to vyřešila priorita vlákna, ale to by na to stejně nemělo vliv.

Kód: [Vybrat]
void threadf() {

while (true) {

wait(200);

unsigned int pins;

ICO300_get_DI(&pins);

for(int i = 0; i <= 8; i++) {

cout << " STAV: " << int(pins & 1) << endl;

pins >> 1;

}


}

}

deadmail

Re:Prioritizace vláken v C
« Odpověď #7 kdy: 19. 08. 2016, 10:46:14 »
co tak
Kód: [Vybrat]
pins = pins >> 1;
?

Re:Prioritizace vláken v C
« Odpověď #8 kdy: 19. 08. 2016, 12:42:01 »
co tak
Kód: [Vybrat]
pins = pins >> 1;
?

Když provedu logický součin (pins & 1) tak to mi tam přiřadí tu jedničku, což by se nemělo vůbec stát, ne????

Neviditelný

Re:Prioritizace vláken v C
« Odpověď #9 kdy: 19. 08. 2016, 13:09:01 »
Kód: [Vybrat]
pins >> 1;
Tento kód nic nedělá, asi jsi myslel
Kód: [Vybrat]
pins >>= 1

Kód: [Vybrat]
int(pins & 1)
je trochu zvláštní konstrukt, i když v tomto případě funkční. Nemyslel jsi ale spíše
Kód: [Vybrat]
(int)(pins & 1)
? V C++ správnější použít
Kód: [Vybrat]
static_cast<int>(pins & 1)

Na závěr máš guláš v operátorech. "&" není logický součin, ale bitwise součet. Logický součin by byl "||".

Neviditelný

Re:Prioritizace vláken v C
« Odpověď #10 kdy: 19. 08. 2016, 13:11:17 »
Na závěr máš guláš v operátorech. "&" není logický součin, ale bitwise součet. Logický součin by byl "||".
Whoops, koukám že s těmi českými termíny mám problém já:) AND = součin = &&, OR = součet = ||.

Re:Prioritizace vláken v C
« Odpověď #11 kdy: 19. 08. 2016, 14:18:25 »
Na závěr máš guláš v operátorech. "&" není logický součin, ale bitwise součet. Logický součin by byl "||".
Whoops, koukám že s těmi českými termíny mám problém já:) AND = součin = &&, OR = součet = ||.

No, já mám spíš návyky z C, v C++ mam trochu guláš, takže já ty chyby už poupravil, ale teď si lámu nad tím, jestli používám správně referenci v tomhle kusu kódu:

Kód: [Vybrat]
uint8_t pins;

ICO300_get_DI(&pins);

uint8_t &stav = pins;

Smysl je načíst osm pinů-bitů přes fci ICO300_get_DI() a referencí to předat další proměnné se kterou už pracuji normálně.
Napadlo mne použít pointer, ale to by byla v tomto případě nejspíš prasárna..

Neviditelný

Re:Prioritizace vláken v C
« Odpověď #12 kdy: 19. 08. 2016, 15:08:42 »
Ta knihovna, kterou používáš je Cčková, takže o žádných C++ových referencích nemá ani tušení. Unární & na pravé straně výrazu funguje v C++ úplně stejně jako v C, takže ICO300_get_DI(&pins) předá té knihovní funkci ukazatel na proměnnou pins.
Kód: [Vybrat]
uint8_t &stav = pins;
vyrobí referenci stav na proměnnou pins. pins i stav budou tedy přestavovat tutéž proměnnou. Proč všude nepoužiješ akorát tu proměnnou pins? Kopírovat si to někam jinam mi nepřijde nijak užitečné.

Re:Prioritizace vláken v C
« Odpověď #13 kdy: 19. 08. 2016, 19:48:19 »
Ta knihovna, kterou používáš je Cčková, takže o žádných C++ových referencích nemá ani tušení. Unární & na pravé straně výrazu funguje v C++ úplně stejně jako v C, takže ICO300_get_DI(&pins) předá té knihovní funkci ukazatel na proměnnou pins.
Kód: [Vybrat]
uint8_t &stav = pins;
vyrobí referenci stav na proměnnou pins. pins i stav budou tedy přestavovat tutéž proměnnou. Proč všude nepoužiješ akorát tu proměnnou pins? Kopírovat si to někam jinam mi nepřijde nijak užitečné.

To jsem tak měl původně, nicméně mi přijde divný, že to prostě neprovede ten logický součin, ale přiřadí mi to tam 1 a kdybych to násobil třema tak mi to do konzole prostě vytiskne jen číslo tři.
Já to budu schopen zase otestovat v pondělí v práci, na tý specifický mašině.

ddfesd

Re:Prioritizace vláken v C
« Odpověď #14 kdy: 19. 08. 2016, 22:06:24 »
ty mas osmibitovou promrnnou pins a z ni chces jednotlive bity ne?

neni lepsi modifikovat vyberovou masku a nekazit pins?!

for(maska=1;maska<=8;maska*=2)
  vyber_bit = pins & maska;