Cum se configurează smartphone-uri și PC-uri. Portal informativ

Utilizarea variabilelor condiționate pentru a gestiona relațiile de sincronizare. Apendice

Pentru a putea implementa logica in program se folosesc operatori conditionali. Conceptual, acești operatori pot fi reprezentați ca puncte nodale, ajungând la care programul alege în care dintre direcțiile posibile să meargă mai departe. De exemplu, trebuie să determinați dacă o variabilă arg conține un număr pozitiv sau negativ și să afișați mesajul corespunzător pe ecran. Pentru a face acest lucru, puteți utiliza instrucțiunea if (if), care efectuează verificări similare.

În cel mai simplu caz, sintaxa pentru o declarație if dată este următoarea:

dacă (expresie)

Dacă valoarea parametrului „expresie” este „adevărat”, instrucțiunea este executată, altfel este omisă de program. Trebuie remarcat faptul că „expresie” este o expresie condiționată în care se verifică o anumită condiție. Masa 2.1 prezintă variante ale expresiilor logice simple ale instrucțiunii if.

Tabelul 2.1. Expresii booleene simple

Să dăm un exemplu de utilizare a operatorului de ramificare if. Următorul program vă permite să determinați semnul variabilei introduse.

Lista 2.1. Primul program pentru determinarea semnului numărului introdus.

#include
int main ()
{
float x;
printf („Introduceți un număr:”);
scanf ("% f", & x);
dacă (x> = 0)

Returnează 0;
}

Analiza textului programului dat arată că doi operatori condiționali pot fi înlocuiți cu unul folosind construcția

dacă (expresie)

care este interpretat astfel. Dacă „expresie” este adevărată, atunci „statement1” este executat, în caz contrar „statement2” este executat. Să rescriem exemplul dat anterior de determinare a semnului unui număr folosind această construcție.

Lista 2.2. Al doilea program pentru determinarea semnului numărului introdus.

#include
int main ()
{
float x;
printf („Introduceți un număr:”);
scanf ("% f", & x);
if (x printf („Numărul introdus% f este negativ. \ n”, x);
altfel
printf („Numărul introdus% f este nenegativ. \ n”, x);

Returnează 0;
}

În exemplele prezentate, după instrucțiunile if și else, există o singură funcție printf (). În cazurile în care trebuie să fie scris mai mult de un operator atunci când este îndeplinită o condiție, trebuie folosite acolade, de ex. utilizați un construct ca

dacă (expresie)
{

}
altfel
{

Trebuie remarcat faptul că, după cuvântul cheie else, puteți pune în mod oficial încă o declarație de condiție if, ca urmare, obținem o construcție și mai flexibilă a tranzițiilor condiționate:

dacă (expresia1)
else if (expresia2)
altfel

Lista 2.3 prezintă un program care implementează ultimul construct de ramură condiționată.

Lista 2.3. Al treilea program pentru determinarea semnului numărului introdus.

#include
int main ()
{
float x;
printf („Introduceți un număr:”);
scanf ("% f", & x);
if (x printf („Numărul introdus% f este negativ. \ n”, x);
altfel dacă (x> 0)
printf („Numărul introdus% f este pozitiv. \ n”, x);
altfel
printf („Numărul introdus% f este nenegativ. \ n”, x);

Returnează 0;
}

Până acum, am luat în considerare condiții simple precum x && - AND logic
|| - SAU logic
! - NR logic

Pe baza acestor trei operații logice pot fi generate condiții mai complexe. De exemplu, dacă există trei variabile exp1, exp2 și exp3, atunci ele pot constitui constructele logice prezentate în tabel. 2.2.

Tabelul 2.2. Exemplu de expresii booleene compuse

La fel ca și operațiile de înmulțire și adunare din matematică, operațiile logice ȘI SAU NU, au și ele priorități proprii. Operațiunea NO are cea mai mare prioritate, adică. o astfel de operaţie se execută mai întâi. Operația ȘI are o prioritate mai mică și, în sfârșit, operația SAU are cea mai mică prioritate. Aceste priorități trebuie luate în considerare la elaborarea unor condiții complexe. De exemplu, starea

if (4 6 || 5 este testat în acest fel. If 4 6 SAU 5 if (4 6 || 5 Instrucțiunea if facilitează scrierea de programe în care trebuie să alegeți între un număr mic de opțiuni posibile. Cu toate acestea, uneori, un program trebuie să selecteze o opțiune dintre multele posibile. În mod formal, puteți utiliza construcția if else if ... else. Cu toate acestea, în multe cazuri se dovedește a fi mai convenabil să utilizați instrucțiunea C ++ switch. sintaxa acestui operator este următoarea:

comutator (variabil)
{
constanta de caz 1:

Caz constant2:

...
Mod implicit:

Acest operator verifică secvenţial pentru egalitatea variabilei cu constantele după cuvântul cheie caz. Dacă niciuna dintre constante nu este egală cu valoarea variabilei, atunci instrucțiunile de după cuvântul default sunt executate. Declarația switch are următoarea particularitate. Să presupunem că valoarea variabilei este egală cu valoarea constantă1 și sunt executate instrucțiunile de după cuvântul cheie primul caz. După aceea, execuția programului va continua prin verificarea variabilei pentru egalitatea constantei2, ceea ce duce adesea la risipa inutilă a resurselor computerului. Pentru a evita această situație, ar trebui să utilizați instrucțiunea break pentru a muta programul la următoarea instrucțiune după comutare.

Lista 2.4 prezintă un exemplu de programare a unei instrucțiuni de comutare condiționată.

Lista 2.4. Un exemplu de utilizare a instrucțiunii switch.

#include
int main ()
{
int x;
printf („Introduceți un număr:”);
scanf („% d”, & x);
comutator (x)
{
cazul 1: printf („Numărul 1 introdus \ n”); break;
cazul 2: printf („Numărul 2 introdus \ n”); pauză;
implicit: printf („Un alt număr introdus \ n”);
}
char ch;
printf („Introduceți un caracter:”);
scanf ("% c", & ch);
comutator (ch)
{
case ‘a’: printf („S-a introdus caracterul a \ n”); pauză;
case ‘b’: printf („Caracterul b \ n introdus”); pauză;
implicit: printf („Un alt caracter \ n introdus”);
}
returnează 0;
}

Acest exemplu demonstrează două cazuri de utilizare diferite pentru instrucțiunea switch. În primul caz se analizează cifra introdusă, în al doilea se analizează caracterul introdus. Trebuie remarcat faptul că acest operator poate face o alegere numai pe baza egalității argumentului său cu una dintre valorile cazului enumerate, i.e. verificarea expresiilor ca x

Variabile condiționale

Variabilă condiționată este un semafor folosit pentru a semnala un eveniment care a avut loc. Unul sau mai multe procese (sau fire) din alte procese sau fire pot aștepta un semnal că a avut loc un eveniment. Ar trebui să înțelegeți diferența dintre variabilele condiționate și semaforele mutex discutate mai sus. Scopul semaforului mutex și al blocărilor de citire/scriere este de a sincroniza accesul la date, în timp ce variabilele de condiție sunt de obicei folosite pentru a sincroniza o secvență de operații. Cu această ocazie, în cartea sa Programare în rețea UNIX W. Richard Stevens a spus foarte bine: „ Mutexurile ar trebui folosite pentru blocare, nu pentru așteptare ».

În Lista 4.6, fluxul de consumatori conținea o buclă:

15 în timp ce (TextFiles.empty ())

Firul „consumator” a iterat prin buclă până la coadă Fișiere text au existat elemente. Această buclă poate fi înlocuită cu o re condiționată m nennaya. Firul producător semnalează consumatorului că articolele au fost plasate în coadă. Firul consumator poate aștepta până când primește un semnal și apoi continuă să proceseze coada.

Variabila condiționată este de tip pthread_cond_t. Următoarele sunt tipurile de operații pe care le poate efectua:

Inițializare;

Distrugere;

așteptare;

Așteptare cu o limită de timp;

Semnalizare adresabilă;

alarma generala;

Operațiile de inițializare și distrugere sunt efectuate de variabile de condiție, similare celor ale altor mutexuri. Funcții de clasă pthread_cond_t, care implementează aceste operațiuni sunt enumerate în tabel. 5.7.

Tabelul 5.7. Funcții ale clasei pthread_cond_t care implementează operațiile variabilelor condiționate

Variabilele condiționate sunt utilizate împreună cu mutexurile. Dacă încercați să blocați un mutex, firul sau procesul se va bloca până când mutex-ul este eliberat. După deblocare, firul sau procesul va primi mutex-ul și își va continua activitatea. Când se utilizează o variabilă condiționată, aceasta trebuie să fie legată de un mutex.

pthread_mutex_lock (& ​​​​Mutex);

pthread_cond_wait (& EventMutex, & Mutex);

pthread_mutex_unlock (& ​​​​Mutex);

Deci o sarcină încearcă să blocheze mutexul. Dacă mutex-ul este deja blocat, atunci această sarcină este blocată. După deblocare, sarcina va elibera mutex-ul Mutexși în același timp va aștepta un semnal pentru variabila condiționată EventMutex . Dacă mutex-ul nu este blocat, sarcina va aștepta la nesfârșit un semnal. Când așteptați cu o limită de timp, sarcina va aștepta un semnal în intervalul de timp specificat. Dacă acest timp expiră înainte ca sarcina să primească un semnal, funcția va returna un cod de eroare. Sarcina va solicita apoi din nou mutexul.

Efectuând semnalizarea adresei, o sarcină notifică un alt fir sau proces că a avut loc un eveniment. Dacă o sarcină așteaptă un semnal pentru o anumită variabilă condiționată, acea sarcină va fi deblocată și va primi un mutex. Dacă mai multe sarcini așteaptă simultan un semnal pentru o anumită variabilă condiționată, atunci doar una dintre ele va fi deblocată. Restul sarcinilor vor aștepta în coadă și vor fi deblocate conform strategiei de programare utilizate. Când se efectuează o operație de semnalizare globală, toate sarcinile care așteaptă un semnal pentru variabila de condiție specificată vor primi notificare. Când mai multe sarcini sunt deblocate, acestea vor concura pentru deținerea mutex-ului în conformitate cu strategia de programare utilizată. Spre deosebire de operația de așteptare, sarcina de semnalizare nu pretinde proprietatea asupra mutexului, deși ar trebui.

Variabila condiționată are și un obiect atribut, ale cărui funcții sunt enumerate în tabel. 5.8.

Tabelul 5.8. Funcții accesorii obiectului de atribut pentru o variabilă condiționată de tip pthread_cond_t


Int pthread_condattr_init(pthread_condattr_t * attr) Inițializează obiectul atribut variabil condiționat specificat de parametrul attr la valorile implicite pentru toate atributele definite de implementare;

Int pthread_condattr_destroy(pthread_condattr_t * attr); Distruge obiectul atribut variabil condiționat specificat de parametrul attr. Acest obiect poate fi reinițializat apelând pthread_condattr_init ()

Int pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared);

Int pthread_condattr_getpshared(const pthread_condattr_t * restrict attr, int * restrict pshared); Setează sau returnează atributul partajat de proces al obiectului atribut variabilă condiționată specificat de parametrul attr. Parametrul pshared poate conține următoarele valori:

PTHREAD_PROCESS_SHARED(permite blocări de citire-scriere partajate de orice fire de execuție care au acces la memoria alocată pentru această variabilă condiționată, chiar dacă firele de execuție aparțin unor procese diferite);

PTHREAD_PROCESS_PRIVATE(Variabila condiționată este partajată între firele de execuție ale aceluiași proces)

Int pthread_condattr_setclock(pthread_condattr_t * attr, clockid_t clock_id);

Int pthread_condattr_getclock(const pthread_condattr_t * restrict attr, clockid_t * restrict clock_id); Setează sau returnează un atribut ceas obiectul atribut al variabilei condiționale specificate de parametru attr... Atribut ceas este identificatorul ceasului folosit pentru a măsura limita de timp în funcția pthread_cond_timedwait (). Atributul ceas este implicit la identificatorul de ceas al sistemului.

Anunţ

Variabil Este o cantitate care are un nume și un sens. Variabilele sunt declarate folosind cuvântul var: var x = 12, y; Aici sunt introduse două variabile cu numele x și y, valoarea 12 este scrisă în variabila x, iar variabila y este nedefinită, adică comanda de urmărire trace (y); va returna nedefinit (valoare nedefinită). Comanda trace (z) produce același rezultat; deoarece variabila z nu este cunoscută deloc. Pentru a distinge o variabilă existentă de una necunoscută, puteți scrie în ea o valoare nulă specială: var y = null;

Dacă tipul variabilei nu este specificat în mod explicit, aceasta poate lua orice valoare. De exemplu:

var x = 1; // numărul x = "Ku-ku!" ; // șir x = fals; // boolean

Cu toate acestea, atunci când declarați, este mai bine să specificați în mod explicit tipul variabilei. Acest lucru permite detectarea multor erori chiar înainte ca programul să fie executat. Există trei tipuri simple:

  • Număr - număr;
  • String - șir;
  • Boolean este o valoare booleană.
Tipul variabilei este indicat după numele acesteia, despărțit de două puncte var x: Number = 0, y: String = "qq", b: Boolean = false; În variabilele de tip String, puteți scrie șiruri de caractere cuprinse între ghilimele sau apostrofe simple: var s1: String = "qq1", s2: String = "qq2"; Variabilele booleene iau doar două valori: adevărat și fals: var b: Boolean = fals; b = adevărat; b = (a În acest din urmă caz, b va fi adevărată dacă condiția din dreapta semnului egal este adevărată.

Dacă încercați să scrieți o valoare de tip greșit într-o variabilă, veți primi un mesaj de eroare imediat când programul este tradus (adică când este tradus în coduri de mașină), și nu în timpul rulării. De exemplu, un cod ca acesta generează o eroare:

var x: Număr = 1; x = "Ku-ku!" ;

Vizibilitate variabila

Există trei tipuri de variabile: Variabilele globale sunt declarate folosind specificatorul _global: _global .x = 12; Rețineți că nu trebuie să utilizați cuvântul var aici, astfel de variabile sunt tratate ca proprietăți ale obiectului _global. Variabila x, care este declarată mai sus, poate fi accesată din orice funcție și din codul oricărui clip pur și simplu după nume.

Dacă există mai multe variabile cu același nume în domeniu, mai întâi se caută variabila locală, apoi variabila clipă curentă și abia apoi variabila globală.

Variabilele altor clipuri sunt „invizibile”; pentru a vă referi la ele, trebuie să indicați în mod explicit clipul părinte:

Mc.x = 1; _rădăcină .x = 12; _părinte .x = 123;

Misiune

Pentru a atribui o nouă valoare unei variabile, utilizați semnul =. În stânga acesteia scrieți numele variabilei, iar în dreapta - expresia: a = 4 * (c + 2) + 3 / (r - 4 * w) + d% 3; Semnul * denotă înmulțirea, semnul / denotă împărțirea și% indică restul împărțirii.

Într-o expresie, operațiile aritmetice sunt efectuate în următoarea ordine:

  • acțiunile între paranteze;
  • înmulțirea, împărțirea și luarea restului (de la stânga la dreapta);
  • adunare si scadere (de la stanga la dreapta).
Această ordine se numește prioritate(de vechime) operații aritmetice.

Șirurile de caractere pot fi „concatenate” folosind operatorul +:

Nu = 20; s = „Vasya” + „a plecat la plimbare”. ; qq = "Obiect" + nu; Dacă în expresie sunt implicate date de diferite tipuri, există o conversie automată la același tip. Deci, în ultima linie, linia Object20 este scrisă în variabila qq.

Operatori ++ ( creştere, crescând variabila cu 1 și - ( scăderea, scăzând variabila cu 1). Operatori

I ++; k -; înseamnă la fel ca i = i + 1; k = k - 1; Există și o notație scurtă pentru operațiile aritmetice: a + = 20; b - = c - d; c * = a + b; d / = 2 * c; f% = 12; Acest cod poate fi înlocuit cu următorii operatori în formă „normală”: a = a + 20; b = b - (c - d); c = c * (a + b); d = d / (2 * c); f = f% 12

Obiecte

Un obiect este ceva care are proprietăți și metode. În mediu Flash există obiecte încorporate (de exemplu, Array, MovieClip, Key). În plus, vă puteți construi propriile obiecte: var car = new Object (); car.v = 10; masina.an = 1998; În mediu Flash puteți folosi programarea orientată pe obiecte, adică să vă creați propriile clase de obiecte, să le dotați cu proprietăți și metode (vezi Subiectul 13).

Caracteristica principală a obiectelor este așa-numita adresare referențială. Adică la declarare

var obj = obiect nou (); variabila obj nu stochează obiectul în sine, ci doar al acestuia adresa(referință la obiect). Prin urmare, operatorul de atribuire obj2 = obj; nu creează un nou obiect în memorie care este o copie a obj, ci pur și simplu copiază adresa primului obiect în obj2. După aceea, obj și obj2 indică același obiect. Dacă vrem cu adevărat să construim o copie a obiectului a cărui adresă este stocată în obj, putem face acest lucru: var obj2 = new Object (); for (prop în obj) obj2 = obj; Aici, bucla iterează peste toate proprietățile primului obiect și le copiază în al doilea. Variabila prop (șir de caractere) este numele următoarei proprietăți. Obj înseamnă „ o proprietate a obiectului obj al cărui nume este stocat în prop».

Variabile condiționale

O variabilă de condiție (condvar - prescurtare pentru variabila de condiție) este folosită pentru a bloca un fir pentru orice condiție în timpul execuției unei secțiuni critice de cod. Condiția poate fi atât de complexă pe cât doriți și nu depinde de variabila condiționată. Cu toate acestea, o variabilă de condiție trebuie întotdeauna utilizată împreună cu un mutex pentru a testa o condiție.

Variabilele condiționate acceptă următoarele funcții:

Așteptați o variabilă condiționată (așteptați) ( pthread_cond_wait ());

Deblocare un singur flux (semnal) ( pthread_cond_signal ())

Deblocarea fluxurilor multiple (difuzare) ( pthread_cond_broadcast ()),

Iată un exemplu de utilizare tipică a unei variabile de condiție:

pthread_mutex_lock (& ​​​​m); - ...

în timp ce (! condiție arbitrară) (

pthread_cond_wait (& cv, & m);

pthread_mutex_unlock (& ​​​​m);

În acest exemplu, capturarea mutexului are loc înainte ca condiția să fie verificată. Astfel, condiția verificată se aplică numai firului curent. Atâta timp cât această condiție este adevărată, această secțiune de cod se blochează în apelul de așteptare până când un alt fir de execuție efectuează o operație de deblocare a unui singur fir de execuție sau mai multe pe o variabilă de condiție.

Bucla while din exemplul de mai sus este necesară din două motive. În primul rând, standardele posix nu garantează că nu există false wake (de exemplu, pe sistemele multiprocesor). În al doilea rând, dacă un alt thread modifică condiția, trebuie să-l retestați pentru a vă asigura că modificarea îndeplinește criteriile acceptate. Când un fir în așteptare este blocat, mutex-ul asociat variabilei condiționate este eliberat atomic de funcție pthread_cond_wait () astfel încât un alt thread să poată intra într-o secțiune critică a codului programului.

Firul care efectuează o singură deblocare pe firul de execuție va debloca firul de execuție cu cea mai mare prioritate care se află în coada variabilei de condiție. O operație de deblocare a mai multor fire de execuție deblochează toate firele aflate în coadă pe o variabilă condiționată. Mutexul asociat cu variabila condițională este eliberat de firul deblocat atomic cu cea mai mare prioritate. După procesarea unei secțiuni critice de cod, acest fir trebuie să elibereze mutex-ul.

Un alt tip de operație care așteaptă o variabilă condiționată ( pthread__cond_timedwair ()) vă permite să setați un timeout. La sfârșitul acestei perioade, firul de așteptare poate fi deblocat.

Bariere

O barieră este un mecanism de sincronizare care vă permite să coordonați activitatea mai multor fire care interacționează în așa fel încât fiecare dintre ele să se oprească la un anumit punct în timp ce așteptați alte fire înainte de a-și continua activitatea.

Spre deosebire de funcție pthreadjoin ()în care un fir așteaptă ca un alt fir să se finalizeze, bariera forțează firele întâlni la un moment dat. După ce numărul specificat de fire atinge bariera stabilită, toate aceste fire se vor debloca și își vor continua munca. Bariera este creată folosind funcția pthread_barrier_init ():

#include

pthread_barrier_init (pthread_barrier_t * barieră, const pthread_barrierattr_t * attr, unsigned int count);

Ca urmare a executării acestui cod, se creează o barieră la adresa dată (pointerul către barieră se află în argumentul barieră) și cu atributele setate de argumentul attr. Argumentul count specifică numărul de fire de execuție de apelat pthread_barrier_wait ().

După ce bariera este creată, fiecare fir apelează funcția pthread_barrier_wait (), semnalând astfel finalizarea acestei acțiuni:

#include

int pthread_barrier_wait (pthread_barrier_t „barieră);

Când firul apelează funcția pthread_barrier_wait (), se blochează până la numărul de fire care a fost specificat de funcție pthread_barrier_init (), nu va apela funcția pthread_jbarrier_wait ()și, în consecință, nu vor fi blocate. După numărul specificat de fire apelează funcția pthread_barrier_wait (), toate se deblochează simultan.

#include

#include

#include

#include

pthread_barrier_t barieră; // obiect de sincronizare de tip „barieră”.

main () // ignoră argumentele

time_t now; // creează o barieră cu o valoare a contorului de 3

pthread_barrier_init (& barieră, NULL, 3); // începe două fire - threadl și thread2

pthread_create (NOLL, NOLL, threadl, NULL); // firele threadl și thread2 sunt executate

pthread_create (NDLL, NDLL, thread2, NDLL); // așteptați finalizarea

printf ("principal () așteaptă bariera la% s", ctime (& acum));

pthread_barrier_wait (& barieră); // după acest punct, toate cele trei fire sunt terminate

printf ("barieră în mainO făcută la% s", ctime (& acum));

threadl (void * nu este folosit)

timp (& acum); // efectuează calcule

printf ("threadl care începe la% s", ctime (& acum)); // pauză

pthread_barrier_wait (& barieră); // după acest punct, toate cele trei fire sunt terminate

printf ("barieră în threadl () făcut la% s", ctime (& acum));

thread2 (void * not__used)

timp (& acum); // efectuează calcule

printf ("thread2 care începe la% s", ctime (& acum)); // pauză

pthread_barrier_wait (& barieră);

// după acest punct toate cele trei fire sunt terminate

printf ("barieră în thread2 () făcut la% s", ctime (& acum));

În exemplul din listare, firul principal creează o barieră, după care începe să numere numărul de fire blocate pe barieră pentru sincronizare. În acest caz, numărul de fire sincronizate este setat la 3: fir principal (), fir1 () și fir2 ().

Firele thread1 () și thread2 () sunt pornite. Pentru claritate, este setată o pauză în flux pentru a simula procesul de calcul. Pentru a efectua sincronizarea, firul principal se blochează pe barieră și așteaptă o deblocare care are loc după ce celelalte două fire nu s-au unit pe această barieră.



Încuietori în așteptare

Blocările Sleepon funcționează într-un mod similar cu variabilele condiționate, cu excepția câtorva detalii. Ca și variabilele condiționate care așteaptă blocări ( pthread_sleepon_lock ()) poate fi folosit pentru a bloca un fir până când o condiție devine adevărată (similar cu schimbarea valorii unei locații de memorie). Dar, spre deosebire de variabilele condiționate (care trebuie să existe pentru fiecare condiție verificată), blocările în așteptare sunt aplicate unui mm.text și unei variabile condiționate create dinamic, indiferent de numărul de condiții testate. Numărul maxim de variabile condiționate este în cele din urmă egal cu numărul maxim de fire blocate.

TAU - teoria controlului automat

TS - sistem tehnic

ОУ - obiect de control

UU - dispozitiv de control

SU - sistem de control

IO - organ executiv

IU - dispozitiv executiv

D - senzor

OS - feedback

PC - raport de transfer

PF - functie de transfer

APFC - răspuns în frecvență amplitudine-fază

Raspuns in frecventa - caracteristica amplitudine-frecventa

LFCH - caracteristică amplitudine-frecvență logaritmică

Caracteristica fază-frecvență - caracteristică fază-frecvență

2. Simboluri ale variabilelor și funcțiilor de bază

X(t) - semnal de intrare al elementului CS, semnal de ieșire al OS și CS (valoare controlată)

y(t) Este semnalul de ieșire al elementului CS, semnalul de intrare al OS (acțiune de control)

X s ( t) Este influența de setare a sistemului de control

z(t) Este efectul perturbator asupra sistemului de control

(t) - semnal de eroare (nepotrivire) în sistemul de control

1(t) - acțiune cu un singur pas

(t) - acţiune cu un singur impuls

X m ,y m- valorile amplitudinii semnalelor X(t) și y(t)

p - operator Laplace, operator de diferențiere

 - frecvenţă circulară, operator transformată Fourier

X(p) - imagine semnal continuu X(t) conform lui Laplace

X(j) - afişare semnal continuu X(t) conform lui Fourier

k - Link PC (sau conexiuni link)

W(p) - legătură PF (sau conexiune de legături)

W(j) - AFC a unei legături (sau a conexiunii de legături)

A() - AFC a unei legături (sau a conexiunii de legături)

 () - caracteristica de fază-frecvență a unei legături (sau a conexiunii de legături)

F ( R) - PF al sistemului de control închis

h(t) - functie tranzitorie (caracteristica) a unei legaturi sau a unui sistem de control

w(t) - funcția de impuls (greutate) (caracteristică) a unei legături sau CS

INTRODUCERE

Teoria controlului automat (TAU)- o disciplină științifică, al cărei subiect îl reprezintă procesele informaționale care au loc în sistemele de control al obiectelor tehnice și tehnologice. TAU dezvăluie modelele generale de funcționare a sistemelor automate de natură fizică diferită și, pe baza acestor modele, dezvoltă principiile construirii sistemelor de control de înaltă calitate.

Când studiază procesele de control în TAU, ei fac abstracție de caracteristicile fizice și de proiectare ale sistemelor și, în loc de sistemele reale, iau în considerare modelele lor matematice adecvate. Cu cât modelul matematic corespunde mai exact (mai complet) proceselor fizice care au loc într-un sistem real, cu atât sistemul de control proiectat va fi mai perfect.

Principalele metode de cercetare la UAT sunt modelarea matematică, teoria ecuațiilor diferențiale ordinare, calculul operațional și analiza armonică. Să aruncăm o privire rapidă la fiecare dintre ele.

Metoda modelării matematice, care combină o mare varietate de metode și tehnici de descriere și prezentare a obiectelor și fenomenelor fizice, poate fi reprezentat condiționat, schematic folosind tehnica cea mai frecvent utilizată - o imagine grafică a unui obiect simplu cu un semnal de intrare X(t) și un semnal de ieșire y(t), sub forma unui dreptunghi (Fig. B. 1, A). Simbol Aîn interiorul dreptunghiului înseamnă un operator matematic (funcție, integrală etc.) care conectează semnalele de intrare și de ieșire care se modifică în timp.

Orez. ÎN 1. Reprezentarea schematică a metodelor matematice utilizate în TAU

Teoria ecuațiilor diferențiale ordinare, concentrându-se pe aspectele fizice și aplicațiile soluțiilor obținute, servește drept bază metodologică principală a TAU, iar ecuațiile diferențiale obișnuite în sine sunt cea mai generală și completă formă de descriere matematică a elementelor și sistemelor de control. Ecuațiile diferențiale relaționează variabilele de intrare și ieșire care variază în timp și derivatele lor. În cel mai simplu caz, ecuația diferențială are forma

dy(t)/dt=f[X(t),y(t)]. (ÎN 1)

Metoda de calcul operațional, care se bazează pe transformarea Laplace

(IN 2)

vă permite să algebrizați ecuații diferențiale - mergeți la așa-numitele ecuații de operator care conectează imagini X(p) și Y(p) a semnalelor de intrare și de ieșire prin funcția de transfer W(p) (fig. B. 1, b)

W(p)=Y(p)/X(p). (LA 3)

Metoda analizei armonice se bazează pe transformata Fourier cunoscută din cursul de matematică, care are forma

(LA 4)

Folosind transformata Fourier (V. 4), imaginile sunt găsite X(j) și Y(j) semnale de intrare şi de ieşire X(t) și y(t) care caracterizează spectrele de frecvenţă ale acestor semnale. Imaginile semnalelor Fourier sunt legate (Figura B. 1, v) funcţia de transfer de frecvenţă

W(j) = Y (j) / X (j). (LA 5)

Toate cele patru metode, prezentate pe scurt mai sus, formează aparatul matematic al TAU. Pe baza acestuia, a fost dezvoltat un complex de metode „proprii” de TAU, prezentate în acest curs.

TAU împreună cu teoria construcției și funcționării elementelor sistemelor de control (senzori, regulatoare, actuatoare) formează o ramură mai largă a științei - automatizarea. Automatizarea, la rândul său, este una dintre ramurile ciberneticii tehnice. Cibernetica tehnică studiază sisteme complexe de control automatizat pentru procese tehnologice (APCS) și întreprinderi (APCS), construite cu ajutorul calculatoarelor de control (CFM).

Cibernetica tehnică, alături de cele biologice și socioeconomice, este o parte integrantă a ciberneticii, pe care fondatorul ei, matematicianul american N. Wiener, a definit-o în 1948 drept știința controlului și comunicării în sistemele tehnice și organismele vii.

Primele regulatoare industriale au apărut între 1765 și 1804. (I. Polzunov, J. Watt, J. Jacquard).

Primele studii teoretice ale regulatorilor au apărut în perioada 1868-1893. (J. Maxwell, I. Vyshnegradsky, A. Stodola). Omul de știință și inginerul rus I.A.Vyshnegradskii a efectuat o serie de studii științifice în care motorul cu abur și regulatorul său au fost analizate pentru prima dată prin metode matematice ca un singur sistem dinamic. Lucrările lui A. A. Andronov, V. S. Kulebakin, I. N. Voznesensky, B. V. Bulgakov, A. A. Feldbaum, B. N. Petrov, N. N. Krasov au jucat un rol important în formarea școlii ruse a TAU. , AA Voronova, Ya. Z. Tsypkina, VS Pugacheva ...

Dezvoltarea teoriei moderne de control din așa-numita teorie „clasică”, bazată pe cele patru metode de cercetare de bază ale TAU menționate mai sus, și formarea celor mai noi metode ale acesteia sunt ilustrate schematic în Fig. ÎN 2.

Orez. ÎN 2. Dezvoltarea conținutului și metodologiei teoriei managementului

În prezent, TAU, împreună cu cele mai recente secțiuni ale teoriei generale a managementului (cercetare operațională, ingineria sistemelor, teoria jocurilor, teoria cozilor de așteptare), joacă un rol important în îmbunătățirea și automatizarea controlului proceselor și industriilor tehnologice.

Top articole similare