Come configurare smartphone e PC. Portale informativo

Utilizzo delle variabili condizionali per gestire le relazioni di sincronizzazione. Appendice

Per poter implementare la logica nel programma, vengono utilizzati operatori condizionali. Concettualmente, questi operatori possono essere rappresentati come punti nodali, raggiungendo i quali il programma sceglie in quale delle possibili direzioni procedere. Ad esempio, è necessario determinare se una variabile arg contiene un numero positivo o negativo e visualizzare il messaggio corrispondente sullo schermo. Per fare ciò, puoi utilizzare l'istruzione if (if), che esegue controlli simili.

Nel caso più semplice, la sintassi per una data istruzione if è la seguente:

se (espressione)

Se il valore del parametro "espressione" è "vero", l'istruzione viene eseguita, altrimenti viene saltata dal programma. Va notato che "espressione" è un'espressione condizionale in cui viene verificata una condizione. Tavolo 2.1 presenta varianti di semplici espressioni logiche dell'istruzione if.

Tabella 2.1. Semplici espressioni booleane

Diamo un esempio dell'uso dell'operatore di ramificazione if. Il seguente programma permette di determinare il segno della variabile inserita.

Listato 2.1. Il primo programma per determinare il segno del numero inserito.

#includere
intero principale ()
{
galleggiante x;
printf ("Inserisci un numero:");
scanf ("% f", & x);
se (x> = 0)

Ritorna 0;
}

L'analisi del testo del programma dato mostra che due operatori condizionali possono essere sostituiti con uno usando la costruzione

se (espressione)

che viene così interpretato. Se "espressione" è vera, viene eseguita "istruzione1", altrimenti viene eseguita "istruzione2". Riscriviamo l'esempio dato in precedenza per determinare il segno di un numero usando questa costruzione.

Listato 2.2. Il secondo programma per determinare il segno del numero inserito.

#includere
intero principale ()
{
galleggiante x;
printf ("Inserisci un numero:");
scanf ("% f", & x);
if (x printf ("Il numero inserito% f è negativo. \ n", x);
altro
printf ("Il numero inserito% f non è negativo. \ n", x);

Ritorna 0;
}

Negli esempi presentati, dopo le istruzioni if ​​e else, c'è solo una funzione printf(). Nei casi in cui è necessario scrivere più di un operatore quando una condizione è soddisfatta, devono essere utilizzate le parentesi graffe, ad es. usa un costrutto come

se (espressione)
{

}
altro
{

Va notato che dopo la parola chiave else, puoi formalmente inserire un'altra istruzione if condition, di conseguenza, otteniamo una costruzione ancora più flessibile delle transizioni condizionali:

se (espressione1)
altrimenti se (espressione2)
altro

Il Listato 2.3 mostra un programma che implementa l'ultimo costrutto di branch condizionale.

Listato 2.3. Il terzo programma per determinare il segno del numero inserito.

#includere
intero principale ()
{
galleggiante x;
printf ("Inserisci un numero:");
scanf ("% f", & x);
if (x printf ("Il numero inserito% f è negativo. \ n", x);
altrimenti se (x> 0)
printf ("Il numero inserito% f è positivo. \ n", x);
altro
printf ("Il numero inserito% f non è negativo. \ n", x);

Ritorna 0;
}

Finora, abbiamo considerato condizioni semplici come x && - AND . logico
|| - OR logico
! - NO . logico

Condizioni più complesse possono essere generate in base a queste tre operazioni logiche. Ad esempio, se ci sono tre variabili exp1, exp2 ed exp3, allora possono costituire i costrutti logici presentati nella tabella. 2.2.

Tabella 2.2. Esempio di espressioni booleane composte

Come le operazioni di moltiplicazione e addizione in matematica, anche le operazioni logiche AND OR NOT hanno le loro priorità. L'operazione NO ha la priorità più alta, ad es. tale operazione viene eseguita per prima. L'operazione AND ha una priorità più bassa e infine l'operazione OR ha la priorità più bassa. Queste priorità devono essere prese in considerazione quando si elaborano condizioni complesse. Ad esempio, la condizione

if (4 6 || 5 è selezionato in questo modo. If 4 6 OR 5 if (4 6 || 5 L'istruzione if rende più facile scrivere programmi in cui è necessario scegliere tra un piccolo numero di possibili opzioni. Tuttavia, a volte un programma deve selezionare un'opzione tra le tante possibili. Formalmente, puoi usare la costruzione if else if ... else. Tuttavia, in molti casi risulta essere più conveniente usare l'istruzione switch C++. la sintassi di questo operatore è la seguente:

interruttore (variabile)
{
caso costante1:

Costante di caso2:

...
predefinito:

Questo operatore verifica in sequenza l'uguaglianza della variabile con le costanti dopo la parola chiave case. Se nessuna delle costanti è uguale al valore della variabile, vengono eseguite le istruzioni dopo la parola default. L'istruzione switch ha la seguente particolarità. Supponiamo che il valore della variabile sia uguale al valore di constant1 e che vengano eseguite le istruzioni dopo la prima parola chiave case. Successivamente, l'esecuzione del programma continuerà controllando la variabile per l'uguaglianza della costante2, che spesso porta a uno spreco inutile di risorse del computer. Per evitare questa situazione, dovresti usare l'istruzione break per spostare il programma all'istruzione successiva dopo lo switch.

Il Listato 2.4 mostra un esempio di programmazione di un'istruzione switch condizionale.

Listato 2.4. Un esempio di utilizzo dell'istruzione switch.

#includere
intero principale ()
{
intero x;
printf ("Inserisci un numero:");
scanf ("% d", & x);
interruttore (x)
{
caso 1: printf ("Numero 1 inserito \ n"); break;
caso 2: printf ("Numero 2 inserito \ n"); rottura;
default: printf ("Un altro numero inserito \ n");
}
char ch;
printf ("Inserisci un carattere:");
scanf ("% c", & ch);
interruttore (ch)
{
caso 'a': printf ("Il carattere a \ n è stato inserito"); rottura;
caso ‘b’: printf (“Carattere b \ n inserito”); rottura;
default: printf ("Un altro carattere \ n inserito");
}
restituisce 0;
}

Questo esempio mostra due diversi casi d'uso per l'istruzione switch. Nel primo caso viene analizzata la cifra inserita, nel secondo viene analizzato il carattere inserito. Va notato che questo operatore può effettuare una scelta solo in base all'uguaglianza del suo argomento con uno dei valori di caso elencati, ad es. controllando espressioni come x

Variabili condizionali

Variabile condizionaleè un semaforo utilizzato per segnalare un evento che si è verificato. Uno o più processi (o thread) di altri processi o thread possono attendere un segnale che si è verificato un evento. Dovresti capire la differenza tra le variabili condizionali e i semafori mutex discussi sopra. Lo scopo del semaforo mutex e dei blocchi di lettura/scrittura è sincronizzare l'accesso ai dati, mentre le variabili di condizione vengono generalmente utilizzate per sincronizzare una sequenza di operazioni. In questa occasione, nel suo libro Programmazione di rete UNIX W. Richard Stevens l'ha detto molto bene: “ I mutex dovrebbero essere usati per bloccare, non per aspettare ».

Nel Listato 4.6, il flusso del consumatore conteneva un ciclo:

15 while (TextFiles.empty ())

Il thread "consumatore" ha ripetuto il ciclo fino alla coda File di testo c'erano elementi. Questo ciclo può essere sostituito con un condizionale re m nennaya. Il thread del produttore segnala al consumatore che gli elementi sono stati inseriti nella coda. Il thread consumer può attendere fino a quando non riceve un segnale e quindi procede all'elaborazione della coda.

La variabile condizionale è di tipo pthread_cond_t. Di seguito sono riportati i tipi di operazioni che può eseguire:

Inizializzazione;

Distruzione;

aspettativa;

In attesa con un limite di tempo;

Segnalazione indirizzata;

Allarme generale;

Le operazioni di inizializzazione e distruzione vengono eseguite da variabili di condizione, simili a quelle di altri mutex. Funzioni di classe pthread_cond_t, che implementano queste operazioni sono elencate nella tabella. 5.7.

Tabella 5.7. Funzioni della classe pthread_cond_t che implementano le operazioni delle variabili condizionali

Le variabili condizionali vengono utilizzate insieme ai mutex. Se si tenta di bloccare un mutex, il thread o il processo si bloccherà finché il mutex non verrà liberato. Dopo lo sblocco, il thread o il processo riceverà il mutex e continuerà il suo lavoro. Quando si utilizza una variabile condizionale, deve essere associata a un mutex.

pthread_mutex_lock (& ​​​​Mutex);

pthread_cond_wait (& EventMutex, & Mutex);

pthread_mutex_unlock (& ​​​​Mutex);

Quindi alcune attività tentano di bloccare il mutex. Se il mutex è già bloccato, questa attività è bloccata. Dopo lo sblocco, l'attività rilascerà il mutex mutex e allo stesso tempo attenderà un segnale per la variabile condizionale EventMutex . Se il mutex non è bloccato, l'attività attenderà un segnale indefinitamente. Quando si attende con un limite di tempo, l'attività attende un segnale entro l'intervallo di tempo specificato. Se questo tempo scade prima che l'attività riceva un segnale, la funzione restituirà un codice di errore. L'attività richiederà quindi nuovamente il mutex.

Eseguendo la segnalazione dell'indirizzo, un'attività notifica a un altro thread o processo che si è verificato un evento. Se un'attività è in attesa di un segnale per una determinata variabile condizionale, tale attività verrà sbloccata e riceverà un mutex. Se più attività sono in attesa di un segnale per una determinata variabile condizionale contemporaneamente, solo una di esse verrà sbloccata. Il resto delle attività attenderà in coda e verrà sbloccato in base alla strategia di pianificazione utilizzata. Quando viene eseguita un'operazione di segnalazione globale, tutte le attività in attesa di un segnale per la variabile di condizione specificata riceveranno una notifica. Quando vengono sbloccate più attività, si contenderanno la proprietà del mutex in base alla strategia di pianificazione utilizzata. A differenza dell'operazione di attesa, l'attività di segnalazione non rivendica la proprietà del mutex, sebbene dovrebbe.

La variabile condizionale ha anche un oggetto attributo, le cui funzioni sono elencate nella tabella. 5.8.

Tabella 5.8. Funzioni di accesso all'oggetto attributo per una variabile condizionale del tipo pthread_cond_t


Int pthread_condattr_init(pthread_condattr_t * attr) Inizializza l'oggetto attributo variabile condizionale specificato dal parametro attr ai valori predefiniti per tutti gli attributi definiti dall'implementazione;

Int pthread_condattr_destroy(pthread_condattr_t * attr); Distrugge l'oggetto attributo variabile condizionale specificato dal parametro attr. Questo oggetto può essere reinizializzato chiamando pthread_condattr_init()

Int pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared);

Int pthread_condattr_getpshared(const pthread_condattr_t * restrizione attr, int * restrizione pshared); Imposta o restituisce l'attributo condiviso dal processo dell'oggetto attributo variabile condizionale specificato dal parametro attr. Il parametro pshared può contenere i seguenti valori:

PTHREAD_PROCESS_SHARED(consente blocchi di lettura-scrittura condivisi da qualsiasi thread che ha accesso alla memoria allocata per questa variabile condizionale, anche se i thread appartengono a processi diversi);

PTHREAD_PROCESS_PRIVATE(La variabile condizionale è condivisa tra i thread dello stesso processo)

Int pthread_condattr_setclock(pthread_condattr_t * attr, clockid_t clock_id);

Int pthread_condattr_getclock(const pthread_condattr_t * restrizione attr, clockid_t * restrizione clock_id); Imposta o restituisce un attributo orologio l'oggetto attributo della variabile condizionale specificata dal parametro attr... Attributo orologioè l'identificatore dell'orologio utilizzato per misurare il limite di tempo nella funzione pthread_cond_timedwait(). L'attributo clock per impostazione predefinita è l'identificatore dell'orologio di sistema.

Annuncio

VariabileÈ una quantità che ha un nome e un significato. Le variabili sono dichiarate usando la parola var: var x = 12, y; Qui vengono introdotte due variabili con i nomi x e y, il valore 12 viene scritto nella variabile x e la variabile y è indefinita, cioè il comando trace trace (y); restituirà undefined (valore non definito). Il comando trace (z) produce lo stesso risultato; perché la variabile z non è affatto nota. Per distinguere una variabile esistente da una sconosciuta, è possibile scrivere in essa uno speciale valore null null: var y = null;

Se il tipo della variabile non è specificato in modo esplicito, può assumere qualsiasi valore. Ad esempio:

variabile x = 1; // numero x = "Ku-ku!" ; // stringa x = falso; // booleano

Tuttavia, quando si dichiara, è meglio specificare esplicitamente il tipo della variabile. Ciò consente di rilevare molti errori anche prima dell'esecuzione del programma. Ci sono tre tipi semplici:

  • Numero - numero;
  • Stringa - stringa;
  • Booleano è un valore booleano.
Il tipo della variabile è indicato dopo il suo nome separato da due punti var x: Number = 0, y: String = "qq", b: Boolean = false; Nelle variabili di tipo String è possibile scrivere stringhe di caratteri racchiuse tra virgolette o singoli apostrofi: var s1: String = "qq1", s2: String = "qq2"; Le variabili booleane assumono solo due valori: true e false: var b: Boolean = false; b = vero; b = (a In quest'ultimo caso, b sarà vero se la condizione a destra del segno di uguale è vera.

Se si tenta di scrivere un valore di tipo errato in una variabile, si riceverà un messaggio di errore immediatamente quando il programma viene tradotto (ovvero quando viene tradotto in codici macchina) e non durante l'esecuzione. Ad esempio, un codice come questo genera un errore:

var x: Numero = 1; x = "Ku-ku!" ;

Visibilità variabile

Esistono tre tipi di variabili: Le variabili globali vengono dichiarate utilizzando l'identificatore _global: _global .x = 12; Nota che non è necessario utilizzare la parola var qui, tali variabili sono trattate come proprietà dell'oggetto _global. La variabile x, dichiarata sopra, è accessibile da qualsiasi funzione e dal codice di qualsiasi clip semplicemente per nome.

Se sono presenti più variabili con lo stesso nome nell'ambito, viene cercata prima la variabile locale, poi la variabile clip corrente e solo dopo la variabile globale.

Le variabili di altre clip sono "invisibili"; per fare riferimento ad esse, devi indicare esplicitamente la clip principale:

Mc.x = 1; _root .x = 12; _genitore .x = 123;

Incarico

Per assegnare un nuovo valore a una variabile, utilizzare il segno =. A sinistra di esso scrivi il nome della variabile e a destra l'espressione: a = 4 * (c + 2) + 3 / (r - 4 * w) + d% 3; Il segno * indica la moltiplicazione, il segno / indica la divisione e% indica il resto della divisione.

In un'espressione, le operazioni aritmetiche vengono eseguite nel seguente ordine:

  • azioni tra parentesi;
  • moltiplicazione, divisione e prendendo il resto (da sinistra a destra);
  • addizione e sottrazione (da sinistra a destra).
Questo ordine si chiama priorità(anzianità) operazioni aritmetiche.

Le stringhe di caratteri possono essere "concatenate" utilizzando l'operatore +:

No = 20; s = "Vasya" + "è andato a fare una passeggiata." ; qq = "Oggetto" + no; Se nell'espressione sono coinvolti dati di tipo diverso, viene eseguita una conversione automatica nello stesso tipo. Quindi nell'ultima riga la riga Object20 viene scritta nella variabile qq.

Operatori ++ ( incremento, aumentando la variabile di 1, e - ( decremento, diminuendo la variabile di 1). operatori

io++; K -; significa lo stesso di i = i + 1; k = k - 1; C'è anche una notazione abbreviata per le operazioni aritmetiche: a + = 20; b - = c - d; c * = a + b; d / = 2 * c; f% = 12; Questo codice può essere sostituito con i seguenti operatori in forma "normale": a = a + 20; b = b - (c - d); c = c * (a + b); d = d / (2 * c); f = f% 12

oggetti

Un oggetto è qualcosa che ha proprietà e metodi. Nell'ambiente Veloce ci sono oggetti incorporati (es. Array, MovieClip, Key). Inoltre, puoi costruire i tuoi oggetti: var car = new Object (); auto.v = 10; auto.anno = 1998; Nell'ambiente Veloceè possibile utilizzare la programmazione orientata agli oggetti, ovvero creare le proprie classi di oggetti, dotarli di proprietà e metodi (vedere l'argomento 13).

La caratteristica principale degli oggetti è il cosiddetto indirizzamento referenziale. Cioè, quando si dichiara

var obj = nuovo oggetto (); la variabile obj non memorizza l'oggetto stesso, ma solo il suo l'indirizzo(riferimento oggetto). Pertanto, l'operatore di assegnazione obj2 = obj; non crea un nuovo oggetto in memoria che sia una copia di obj, ma semplicemente copia l'indirizzo del primo oggetto in obj2. Successivamente, obj e obj2 puntano allo stesso oggetto. Se davvero vogliamo costruire una copia dell'oggetto il cui indirizzo è memorizzato in obj, possiamo fare questo: var obj2 = new Object (); for (prop in obj) obj2 = obj; Qui, il ciclo itera su tutte le proprietà del primo oggetto e le copia nel secondo. La variabile prop (stringa di caratteri) è il nome della proprietà successiva. Obj significa " una proprietà dell'oggetto obj il cui nome è memorizzato in prop».

Variabili condizionali

Una variabile di condizione (condvar - abbreviazione di variabile di condizione) viene utilizzata per bloccare un thread per qualsiasi condizione durante l'esecuzione di una sezione critica di codice. La condizione può essere complessa a piacimento e non dipende dalla variabile condizionale. Tuttavia, una variabile di condizione deve essere sempre utilizzata insieme a un mutex per verificare una condizione.

Le variabili condizionali supportano le seguenti funzioni:

In attesa di una variabile condizionale (wait) ( pthread_cond_wait ());

Sblocco flusso singolo (segnale) ( pthread_cond_signal ())

Sblocco di flussi multipli (trasmissione) ( pthread_cond_broadcast ()),

Ecco un esempio di uso tipico di una variabile di condizione:

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

while (! condizione arbitraria) (

pthread_cond_wait (& cv, & m);

pthread_mutex_unlock (& ​​​​m);

In questo esempio, l'acquisizione del mutex avviene prima che la condizione venga verificata. Pertanto, la condizione selezionata si applica solo al thread corrente. Finché questa condizione è vera, questa sezione di codice si blocca sulla chiamata di attesa finché un altro thread non esegue un'operazione di sblocco di uno o più thread su una variabile di condizione.

Il ciclo while nell'esempio precedente è richiesto per due motivi. Innanzitutto, gli standard posix non garantiscono che non vi siano false scia (ad esempio, su sistemi multiprocessore). In secondo luogo, se un altro thread modifica la condizione, è necessario ripetere il test per assicurarsi che la modifica soddisfi i criteri accettati. Quando un thread in attesa viene bloccato, il mutex associato alla variabile condizionale viene rilasciato atomicamente dalla funzione pthread_cond_wait () in modo che un altro thread possa inserire una sezione critica del codice del programma.

Il thread che esegue un singolo sblocco sul thread sbloccherà il thread con la priorità più alta che si trova nella coda sulla variabile di condizione. Un'operazione di sblocco di più thread sblocca tutti i thread in coda su una variabile condizionale. Il mutex associato alla variabile condizionale viene liberato dal thread non bloccato atomicamente con la priorità più alta. Dopo aver elaborato una sezione critica del codice, questo thread deve rilasciare il mutex.

Un altro tipo di operazione in attesa di una variabile condizionale ( pthread__cond_timedwair ()) consente di impostare un timeout. Al termine di questo periodo, il thread in attesa può essere sbloccato.

barriere

Una barriera è un meccanismo di sincronizzazione che consente di coordinare il lavoro di più thread interagenti in modo tale che ciascuno di essi si fermi in un determinato punto in attesa di altri thread prima di continuare il proprio lavoro.

A differenza della funzione pthreadjoin () in cui un thread è in attesa del completamento di un altro thread, la barriera forza i thread incontrare ad un certo punto. Dopo che il numero specificato di thread raggiunge la barriera impostata, tutto questi thread si sbloccheranno e continueranno il loro lavoro. La barriera viene creata utilizzando la funzione pthread_barrier_init():

#includere

pthread_barrier_init (pthread_barrier_t * barriera, const pthread_barrierattr_t * attr, conteggio int senza segno);

Come risultato dell'esecuzione di questo codice, viene creata una barriera all'indirizzo dato (il puntatore alla barriera si trova nell'argomento barriera) e con gli attributi impostati dall'argomento attr. L'argomento count specifica il numero di thread da chiamare pthread_barrier_wait().

Dopo che la barriera è stata creata, ogni thread chiama la funzione pthread_barrier_wait(), segnalando così il completamento di questa azione:

#includere

int pthread_barrier_wait (pthread_barrier_t "barriera);

Quando il thread chiama la funzione pthread_barrier_wait (), si blocca fino al numero di thread specificato dalla funzione pthread_barrier_init (), non chiamerà la funzione pthread_jbarrier_wait () e, di conseguenza, non verrà bloccato. Dopo il numero specificato di thread chiama la funzione pthread_barrier_wait (), si sbloccano tutti contemporaneamente.

#includere

#includere

#includere

#includere

pthread_barrier_t barriera; // oggetto di sincronizzazione di tipo "barriera"

main() // ignora gli argomenti

time_t now; // crea una barriera con un controvalore di 3

pthread_barrier_init (& barriera, NULL, 3); // avvia due thread: threadl e thread2

pthread_create (NOLL, NOLL, threadl, NULL); // vengono eseguiti i thread threadl e thread2

pthread_create (NDLL, NDLL, thread2, NDLL); // attendi il completamento

printf ("main () in attesa della barriera at% s", ctime (& now));

pthread_barrier_wait (& barriera); // dopo questo punto tutti e tre i thread sono terminati

printf ("barriera in mainO fatta a% s", ctime (& ora));

threadl (vuoto * non utilizzato)

adesso); // esegue i calcoli

printf ("threadl che inizia a% s", ctime (& ora)); // pause

pthread_barrier_wait (& barriera); // dopo questo punto tutti e tre i thread sono terminati

printf ("barriera in threadl () done at% s", ctime (& now));

thread2 (vuoto * non__utilizzato)

adesso); // esegue i calcoli

printf ("thread2 che inizia a% s", ctime (& ora)); // pause

pthread_barrier_wait (& barriera);

// dopo questo punto tutti e tre i thread sono finiti

printf ("barriera nel thread2 () eseguita a% s", ctime (& ora));

Nell'esempio del listato, il thread principale crea una barriera, dopo di che inizia a contare il numero di thread bloccati sulla barriera per la sincronizzazione. In questo caso, il numero di thread sincronizzati è impostato su 3: thread principale (), thread1 () e thread2 ().

Vengono avviati i thread thread1() e thread2(). Per chiarezza, viene impostata una pausa nel flusso per simulare il processo di calcolo. Per eseguire la sincronizzazione, il thread principale si blocca sulla barriera e attende uno sblocco che si verifica dopo che gli altri due thread non si sono uniti a questa barriera.



Serrature in sospeso

I blocchi Sleepon funzionano in modo simile alle variabili condizionali, tranne per alcuni dettagli. Come le variabili condizionali in attesa di blocchi ( pthread_sleepon_lock ()) può essere utilizzato per bloccare un thread finché una condizione non diventa vera (in modo simile alla modifica del valore di una posizione di memoria). Ma a differenza delle variabili condizionali (che devono esistere per ogni condizione da testare), i blocchi in sospeso vengono applicati a un mm.text e a una variabile condizionale creata dinamicamente, indipendentemente dal numero di condizioni da testare. Il numero massimo di variabili condizionali alla fine è uguale al numero massimo di thread bloccati.

TAU - teoria del controllo automatico

TS - sistema tecnico

ОУ - oggetto di controllo

UU - dispositivo di controllo

SU - sistema di controllo

IO - organo esecutivo

IU - dispositivo esecutivo

D - sensore

Sistema operativo - feedback

PC - rapporto di trasferimento

PF - funzione di trasferimento

APFC - risposta in frequenza ampiezza-fase

Risposta in frequenza - caratteristica ampiezza-frequenza

LFCH - caratteristica ampiezza-frequenza logaritmica

Caratteristica di frequenza di fase - caratteristica di frequenza di fase

2. Simboli di variabili e funzioni di base

X(T) - segnale di ingresso dell'elemento CS, segnale di uscita di OS e CS (valore controllato)

(T) È il segnale di uscita dell'elemento CS, il segnale di ingresso del sistema operativo (azione di controllo)

X S ( T) È l'influenza dell'impostazione del sistema di controllo?

z(T) È l'effetto di disturbo sul sistema di controllo?

(T) - segnale di errore (mismatch) nel sistema di controllo

1(T) - azione a passo singolo

(T) - azione a singolo impulso

X m , m- valori di ampiezza dei segnali X(T) e (T)

P - Operatore di Laplace, operatore di differenziazione

 - frequenza circolare, operatore di trasformata di Fourier

X(P) - immagine del segnale continuo X(T) secondo Laplace

X(J) - visualizzazione continua del segnale X(T) secondo Fourier

K - Collegamento PC (o collegamenti di collegamento)

W(P) - Collegamento PF (o collegamento di collegamenti)

W(J) - AFC di un collegamento (o collegamento di collegamenti)

UN() - AFC di un collegamento (o collegamento di collegamenti)

 () - caratteristica di frequenza di fase di un collegamento (o connessione di collegamenti)

F ( R) - PF del sistema di controllo chiuso

h(T) - funzione transitoria (caratteristica) di un collegamento o sistema di controllo

w(T) - funzione impulso (peso) (caratteristica) di un collegamento o CS

INTRODUZIONE

Teoria del controllo automatico (TAU)- una disciplina scientifica, il cui oggetto sono i processi di informazione che si verificano nei sistemi di controllo di oggetti tecnici e tecnologici. TAU rivela gli schemi generali di funzionamento dei sistemi automatici di varia natura fisica e, sulla base di questi schemi, sviluppa i principi per costruire sistemi di controllo di alta qualità.

Quando studiano i processi di controllo in TAU, astraggono dalle caratteristiche fisiche e progettuali dei sistemi e invece dei sistemi reali considerano i loro modelli matematici adeguati. Quanto più accuratamente (più completamente) il modello matematico corrisponde ai processi fisici che avvengono in un sistema reale, tanto più perfetto sarà il sistema di controllo progettato.

I principali metodi di ricerca presso TAU ​​sono la modellazione matematica, la teoria delle equazioni differenziali ordinarie, il calcolo operativo e l'analisi armonica. Diamo una rapida occhiata a ciascuno di essi.

Metodo di modellazione matematica, combinando un'ampia varietà di metodi e tecniche per descrivere e presentare oggetti e fenomeni fisici, può essere rappresentato in modo condizionale e schematico utilizzando la tecnica più comunemente usata: un'immagine grafica di un semplice oggetto con un segnale di ingresso X(T) e un segnale di uscita (T), a forma di rettangolo (Fig. B. 1, un). Simbolo UN all'interno del rettangolo si intende un operatore matematico (funzione, integrale, ecc.) che collega i segnali di ingresso e di uscita che cambiano nel tempo.

Riso. IN 1. Rappresentazione schematica dei metodi matematici utilizzati in TAU

Teoria delle equazioni differenziali ordinarie, concentrandosi sugli aspetti fisici e sulle applicazioni delle soluzioni ottenute, funge da principale base metodologica del TAU e le equazioni differenziali ordinarie sono la forma più generale e completa di descrizione matematica di elementi e sistemi di controllo. Le equazioni differenziali mettono in relazione variabili di input e output variabili nel tempo e le loro derivate. Nel caso più semplice, l'equazione differenziale ha la forma

dy(T)/dt=F[X(T),(T)]. (IN 1)

Metodo del calcolo operazionale, che si basa sulla trasformata di Laplace

(IN 2)

ti permette di algebrare le equazioni differenziali - vai alle cosiddette equazioni degli operatori che collegano le immagini X(P) e (P) dei segnali di ingresso e di uscita tramite la funzione di trasferimento W(P) (fig. B. 1, B)

W(P)=(P)/X(P). (ALLE 3)

Metodo di analisi armonica si basa sulla trasformata di Fourier nota dal corso di matematica, che ha la forma

(AT 4)

Usando la trasformata di Fourier (V. 4), si trovano le immagini X(J) e (J) segnali di ingresso e uscita X(T) e (T) che caratterizzano gli spettri di frequenza di questi segnali. Le immagini dei segnali di Fourier sono collegate (Figura B. 1, v) funzione di trasferimento di frequenza

W(J) = Y (j) / X (j). (ALLE 5)

Tutti e quattro i metodi, brevemente presentati sopra, formano l'apparato matematico di TAU. Sulla base di esso, è stato sviluppato un complesso di metodi "propri" di TAU, presentati in questo corso.

TAU insieme alla teoria della costruzione e del funzionamento degli elementi dei sistemi di controllo (sensori, regolatori, attuatori) costituisce un ramo più ampio della scienza: l'automazione. L'automazione, a sua volta, è uno dei rami della cibernetica tecnica. La cibernetica tecnica studia sistemi di controllo automatizzato complessi per processi tecnologici (APCS) e imprese (APCS), costruiti utilizzando computer di controllo (CFM).

La cibernetica tecnica, insieme a quella biologica e socioeconomica, è parte integrante della cibernetica, che il suo fondatore, il matematico americano N. Wiener, definì nel 1948 come la scienza del controllo e della comunicazione nei sistemi tecnici e negli organismi viventi.

I primi regolatori industriali apparvero tra il 1765 e il 1804. (I. Polzunov, J. Watt, J. Jacquard).

I primi studi teorici sui regolatori apparvero nel periodo 1868-1893. (J. Maxwell, I. Vyshnegradsky, A. Stodola). Lo scienziato e ingegnere russo I.A.Vyshnegradskii ha condotto una serie di studi scientifici in cui il motore a vapore e il suo regolatore sono stati inizialmente analizzati con metodi matematici come un unico sistema dinamico. Le opere di A. A. Andronov, V. S. Kulebakin, I. N. Voznesensky, B. V. Bulgakov, A. A. Feldbaum, B. N. Petrov, N. N. Krasov hanno svolto un ruolo importante nella formazione della scuola russa di TAU. , AA Voronova, Ya. Z. Tsypkina, VS ...

Lo sviluppo della moderna teoria del controllo dalla cosiddetta teoria della regolazione "classica", basata sui quattro metodi di ricerca di base del TAU sopra menzionati, e la formazione dei suoi metodi più recenti sono schematicamente illustrati in Fig. IN 2.

Riso. IN 2. Sviluppo del contenuto e della metodologia della teoria del management

Attualmente, TAU, insieme alle ultime sezioni della teoria del controllo generale (ricerca operativa, ingegneria dei sistemi, teoria dei giochi, teoria delle code), svolge un ruolo importante nel miglioramento e nell'automazione del controllo dei processi tecnologici e delle industrie.

Principali articoli correlati