How to set up smartphones and PCs. Informational portal

Appendix. ActionScript Basics

In order to be able to implement logic in the program, conditional statements are used. Speculatively, these operators can be represented as key points, reaching which the program makes a choice in which of the possible directions to move on. For example, you want to determine whether some variable arg contains a positive or negative number and display the appropriate message on the screen. To do this, you can use the if statement (if), which performs such checks.

In the very simple case the syntax of this if statement is as follows:

if (expression)

If the value of the expression parameter is true, the statement is executed, otherwise it is skipped by the program. It should be noted that "expression" is conditional expression, in which some condition is checked. In table. 2.1 presents options for simple boolean expressions if statement.

Table 2.1. Simple boolean expressions

Here is an example of using the if branch operator. The following program allows you to determine the sign of the entered variable.

Listing 2.1. The first program to determine the sign of the entered number.

#include
int main()
{
float x;
printf("Enter number: ");
scanf(“%f”,&x);
if(x >= 0)

return 0;
}

An analysis of the above program text shows that two conditional statements can be replaced by one using the construction

if (expression)

which is interpreted in this way. If "expression" is true, then "statement1" is executed, otherwise "statement2" is executed. Let's rewrite the previously given example of determining the sign of a number using this construction.

Listing 2.2. The second program for determining the sign of the entered number.

#include
int main()
{
float x;
printf("Enter number: ");
scanf(“%f”,&x);
if(x printf(“The entered number %f is negative.\n”, x);
else
printf("The entered number %f is non-negative.\n", x);

return 0;
}

In the presented examples, after the if and else statements, there is only one printf function(). In cases where more than one operator must be written under a certain condition, it is necessary to use braces, i.e. use a construct like

if (expression)
{

}
else
{

It should be noted that after keyword else formally, you can put one more if condition statement, as a result we get an even more flexible construction of conditional transitions:

if(expression1)
else if(expression2)
else

Listing 2.3 shows the program that implements the last conditional jump construct.

Listing 2.3. The third program for determining the sign of the entered number.

#include
int main()
{
float x;
printf("Enter number: ");
scanf(“%f”,&x);
if(x printf(“The entered number %f is negative.\n”, x);
else if(x > 0)
printf("Entered number %f is positive.\n", x);
else
printf("The entered number %f is non-negative.\n",x);

return 0;
}

So far considered simple conditions type x && - logical AND
|| - logical OR
! - logical NO

Based on these three logical operations, more complex conditions can be formed. For example, if there are three variables exp1, exp2 and exp3, then they can constitute the logical constructions presented in Table. 2.2.

Table 2.2. Example of compound logical expressions

Like the operations of multiplication and addition in mathematics, logical operations AND OR NOT also have their own priorities. The NO operation has the highest priority, i.e. such an operation is performed first. The AND operator has the lowest priority, and finally the OR operator has the lowest priority. These priorities must be taken into account when drafting complex conditions. For example, the condition

if(4 6 || 5 is checked in this way. If 4 6 OR 5 if(4 6 || 5 Conditional operation if makes it easy to write programs that require you to choose between few options. However, sometimes in the program it is necessary to select one option from a variety of possible ones. Formally, you can use the if else if ... else construct for this. However, in many cases it is more convenient to use the C++ switch statement. The syntax of this operator is as follows:

switch(variable)
{
case constant1:

Case constant2:

...
default:

This operator sequentially checks for equality variable to constants, after the case keyword. If none of the constants is equal to the value of the variable, then the statements after the word default are executed. The switch statement has the following feature. Suppose the value of the variable is equal to the value of the constant1 and the statements after the first case keyword are executed. After that, the program execution will continue by checking the variable for the equality of the constant2, which often leads to unjustified expenditure of computer resources. To avoid this situation, you should use break statement to jump to the next statement after the switch.

Listing 2.4 shows a programming example conditional statement switch.

Listing 2.4. An example of using the switch statement.

#include
int main()
{
intx;
printf("Enter number: ");
scanf("%d",&x);
switch(x)
{
case 1: printf("Entered number 1\n");break;
case 2: printf("Entered number 2\n"); break;
default: printf("Another number has been entered\n");
}
charch;
printf("Enter character: ");
scanf("%c",&ch);
switch(ch)
{
case ‘a’ : printf(“Character a\n entered”); break;
case 'b' : printf("Entered character b\n"); break;
default: printf(“Another character entered\n”);
}
return 0;
}

This example demonstrates two different options use of the switch statement. In the first case, the analysis of the entered digit is performed, in the second case, the analysis of the entered character. It should be noted that given operator can make a choice only based on the equality of its argument to one of the listed case values, i.e. checking expressions of type x

You can store knowledge about the interlocutors or any other text information. Now, when writing templates, you can use 13 variables that have a predetermined purpose, and 100 "free" variables that info owners can use at their discretion.
Variables with a given purpose have "speaking" names. For example, %username is a variable designed to store the name of the interlocutor. Used in her name English words user ("user") and name ("name"). Such variables are actively used by developers when creating a database of standard info templates, on the basis of which all user info is created in the project.
The lifetime of such variables is not limited, i.e. their meanings are remembered and stored between individual conversations.

What is written in the templates Dialogue example
Remembering the name:
$ My name is *
# Nice to meet you. [%username="[*1]"]
The guest: My name is Vasya
Info: Once to meet.
We display the name of the interlocutor in the response infa:
$ Bye, inf.
# Goodbye, [%user_name]
The guest: So far, inf.
Info: Goodbye, Vasya.
Choose an answer depending on the value of the %user_name variable:
$ Do you remember my name?
# (Of course. You are [%user_name].)
# (No. You didn't tell me your name.)
The guest: Do you remember what my name is?
Info: Certainly. You are Vasya.
or
The guest: Do you remember what my name is?
Info: No. You didn't tell me your name.
We do not want to store the name of the interlocutor anymore, we reset the variable
$ You are a fool.
# That's it, I'm no longer friends with you, and I forgot your name. [%username=""]
The guest: You're a fool.
Info: That's it, I'm no longer friends with you, and I forgot your name.

Assigning a value to a variable and resetting a variable

You can assign a value to a variable or reset it in infa answers.

Syntax:[%variable = "value"]
The variable assignment command is always surrounded by square brackets, which are service symbols here. The value of a variable is always in quotes.
Value assignment examples:
$ I dance rock and roll.
# I envy. Info cannot dance [%var1="dancing"]

$*hate*dance*
$*dance*hate*
$ *not dancing*
# It's a pity. If I were human, I would definitely dance. [%var1="doesn't like dancing"]

$ I'm ** years old.
# Cool age! [%user_age="[*1]"]

An example of zeroing a variable:
$ I don't want you to talk about my age.
# As you say [%user_age=""]

Assigning a value to a variable using the set function

Function set("Argument1", "Argument2", "Argument3") substitutes Argument2 in its place and assigns its value to the variable specified in Argument1. Argument3 defaults to the empty string. If it is specified as different from empty string, then in place set functions no text will be substituted and only the assignment of the value to the variable will occur.

For example,
$ my name is **
#Nice to meet you, [@set("user_name", "[@ ("[*1]")]")]!

The guest: my name is Vasya
Info: Nice to meet you, Vasya!

Or:
$ my name is **
# I'll remember your name. [@set("user_name", "[@("[*1]")]", "1")]

$*what is*my*name*
# You are [%user_name].

The guest: My name is Lena
Info: I will remember your name.
The guest: Well, what's my name?
Info: You are Lena.

Displaying the value of a variable in the infa response

In order for inf to "voice" the value of a variable in the answer, you just need to write this variable in the answer.
Syntax:[%variable]
The square brackets are required.

Example:
$ Bye, robot!
# Goodbye, [%user_name]!

A condition variable can be used to implement the timing relationships mentioned above: start-to-start (CC), finish-to-start (FS), start-to-finish (SF), and finish-to-finish (FF). These relationships can exist between threads of the same or different processes. Listings 5.4 and 5.5 show implementation examples of FS and FF synchronization relationships. In each example, two mutexes are defined. One mutex is used to synchronize access to shared data, and the other is used to synchronize code execution.

// Listing 5.4. FS timing relationship between

// two threads

pthread_t ThreadA,ThreadB;

pthread_cond_t Event;

void* worker1(void*X) (

for(int Count = l; Count

pthread_mutex_lock(&Mutex);

pthread_mutex_unlock(&Mutex);

if(Number == 50)(

pthread_cond_signal(&Event);

void* worker2(void*X) (

pthread_mutex_lock(&EventMutex);

pthread_cond_wait(&Event,&EventMutex);

for(int Count = 1; Count

pthread_mutex_lock(&Mutex);

Number = Number + 20;

pthread_mutex_unlock(&Mutex);

cout ""Worker2 has ended." "endl; return(0);

int main(int argc, char *argv) (

pthread_mutex_init(&Mutex, NULL);

pthread_mutex_init(&EventMutex, NULL);

pthread_cond_init(&Event, NULL);

pthread_create(&ThreadA, NULL, workerl, NULL);

pthread_create(&ThreadB, NULL, worker2 , NULL);

Listing 5.4 shows an example implementation of a FS synchronization relationship. ThreadA cannot terminate until ThreadB starts. If the value of the Number variable becomes 50, ThreadA signals this to ThreadB. It can now continue executing until the very end. ThreadB cannot start executing until it receives a signal from ThreadA. ThreadB uses the EventMutex object along with the Event condition variable. The Mutex object is used to synchronize access to write the value of the shared variable Number. A task can use multiple mutexes to synchronize various events and access critical sections.

An example implementation of FF timing relationships is shown in Listing 5.5.

// Listing 5.5. FF synchronization relationship between // two threads

pthread_t ThreadA, ThreadB ;

pthread_mutex_t Mutex, EventMutex;

pthread_cond_t Event;

void *worker(void *X) (

for(int Count = l; Count

pthread_mu tex_l ock(&Mutex);

pthread_mutex_unlock(&Mutex);

cout " "workerl: number is "

pthread_mutex_lock(&EventMutex) ,-

cout " "Function workerl is waiting. " "endl;

pthread_cond_wait (&Event, &EventMutex) ;

pthread_mutex_unlock(&EventMutex);

void *worker2 (void *X) (

for(int Count = l; Count

pthread_mutex_lock(&Mutex) ;

Number = Number * 2 ;

pthread_mutex_unlock(&Mutex) ;

cout " "worker2: number is " " Number " endl;

pthread_cond_signal(&Event) ;

cout " "Function worker2 sent a signal " " endl; return(0);

int main(int argc, char *argv) (

pthread_mutex_init (&Mutex,NULL) ;

pthread_mutex_init (&EventMutex,NULL) ;

pthread_cond_init (&Event, NULL) ;

pthread_create(&ThreadA, NULL,workerl, NULL);

pthread_create(&ThreadB, NULL, worker2, NULL) ;

In Listing 5.5, ThreadA cannot terminate until ThreadB terminates. ThreadA must loop 10 times, and ThreadB must loop 100. ThreadA will complete its iterations before ThreadB, but will wait until ThreadB signals its completion.

CC and SF timing relationships cannot be implemented In a similar way. These methods are used to synchronize pores I for execution I processes.

TAU - automatic control theory

TS - technical system

OS - control object

UU - control device

SU - control system

IO - executive body

IU - executive device

D - sensor

OS - feedback

PC - gear ratio

TF - transfer function

AFC - amplitude-phase frequency response

AFC - amplitude-frequency characteristic

LAFC - logarithmic amplitude-frequency characteristic

PFC - phase-frequency response

2. Conventions for the main variables and functions

x(t) is the input signal of the CS element, the output signal of the OS and CS (controlled variable)

y(t) is the output signal of the CS element, the input signal of the OS (control action)

x h ( t) is the master action of the CS

z(t) is the disturbing effect on the control system

(t) is an error (mismatch) signal in the CS

1(t) is a single step action

(t) is a single impulse action

x m ,y mamplitude values signals x(t) And y(t)

p – Laplace operator, differentiation operator

 - circular frequency, Fourier transform operator

X(p) – continuous signal image x(t) according to Laplace

X(j) - continuous signal image x(t) by Fourier

k – Link PC (or link connections)

W(p) - PF of a link (or connection of links)

W(j) - AFC of a link (or connection of links)

BUT() - frequency response of the link (or connection of links)

() – PFC of a link (or connection of links)

F( R) is the PF of a closed control system

h(t) is the transition function (characteristic) of the link or CS

w(t) is the impulse (weight) function (characteristic) of the link or CS

INTRODUCTION

Theory of automatic control (TAU)- a scientific discipline, the subject of which is the information processes occurring in the control systems of technical and technological objects. TAU reveals the general patterns of functioning of automatic systems of various physical nature and, on the basis of these patterns, develops principles for constructing high-quality control systems.

When studying control processes in TAU, they abstract from the physical and design features of systems and instead of real systems consider their adequate mathematical models. The more accurately (more fully) the mathematical model corresponds to the physical processes occurring in a real system, the more perfect the designed control system will be.

The main research methods at TAU ​​are mathematical modeling, the theory of ordinary differential equations, operational calculus and harmonic analysis. Let's briefly consider each of them.

Method of mathematical modeling, which combines a wide variety of methods and techniques for describing and representing physical objects and phenomena, can be conditionally, schematically represented using the most commonly used technique - a graphical representation of a simple object that has one input signal x(t) and one output signal y(t), in the form of a rectangle (Fig. B. 1, but). Symbol BUT inside a rectangle means some mathematical operator (function, integral, etc.) that connects the input and output signals that change in time.

Rice. IN 1. Schematic representation of the mathematical methods used in TAU

Theory of ordinary differential equations, which focuses its attention on the physical aspects and applications of the solutions obtained, serves as the main methodological basis of the TAU, and the ordinary differential equations themselves are the most general and complete form of the mathematical description of elements and control systems. Differential equations relate time-varying input and output variables and their derivatives. In the simplest case, the differential equation has the form

dy(t)/dt=f[x(t),y(t)]. (IN 1)

Operational calculus method, which is based on the Laplace transform

(IN 2)

allows you to algebraize differential equations - go to the so-called operator equations linking images X(p) And Y(p) input and output signals through the transfer function W(p) (Fig. B. 1, b)

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

Harmonic analysis method is based on the Fourier transform known from the course of mathematics, which has the form

(AT 4)

Using the Fourier transform (V. 4), images are found X(j) and Y(j) input and output signals x(t) And y(t) characterizing the frequency spectra of these signals. Fourier signal images are connected (Fig. B. 1, in) frequency transfer function

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

All four methods, briefly presented above, form the mathematical apparatus of TAU. On its basis, a set of "own" methods of TAU, presented in this course, has been developed.

TAU, together with the theory of construction and operation of elements of control systems (sensors, regulators, actuators) forms a broader branch of science - automation. Automation, in turn, is one of the branches of technical cybernetics. Technical cybernetics studies complex automated process control systems (APCS) and enterprises (APCS) built using control computers (CCMs).

Technical cybernetics, along with biological and socioeconomic ones, is an integral part of cybernetics, which its founder, the American mathematician N. Wiener, defined in 1948 as the science of control and communication in technical systems and living organisms.

The first industrial regulators appeared in the period 1765-1804. (I. Polzunov, J. Watt, J. Jaccard).

The first theoretical studies of regulators appeared in the period 1868-1893. (J. Maxwell, I. Vyshnegradsky, A. Stodola). Russian scientist and engineer I. A. Vyshnegradsky completed a number of scientific research, in which the steam engine and its regulator were first analyzed by mathematical methods as a single dynamic system. The works of A. A. Andronov, V. S. Kulebakin, I. N. Voznesensky, B. V. Bulgakov, A. A. Feldbaum, B. N. Petrov, N. N. Krasovsky , A. A. Voronova, Ya. Z. Tsypkina, V. S. Pugacheva, ...

The development of modern control theory from the so-called "classical" control theory, based on the four above-mentioned basic methods for studying TAU, and the formation of its latest methods are schematically illustrated in Fig. IN 2.

Rice. IN 2. Development of the content and methodology of control theory

At present, TAU along with the latest sections general control theory (operations research, systems engineering, game theory, queuing theory) plays a crucial role in improving and automating the management of technological processes and industries.

Condition variables

A condition variable (condvar is short for condition variable) is used to block a thread on some condition during the execution of a critical section of code. The condition can be arbitrarily complex and does not depend on the condition variable. However, a condition variable should always be used in conjunction with a mutex to test a condition.

Condition variables support following features:

waiting for a conditional variable (wait) ( pthread_cond_wait());

a single stream unlock (signal) ( pthread_cond_signal())

multiple stream unblocking (broadcast) ( pthread_cond_broadcast()),

Here is an example of a typical use of a condition variable:

pthread_mutex_lock (&m) ;-…

while (!arbitrary condition) (

pthread_cond_wait(&cv, &m);

pthread_mutex_unlock(&m) ;

In this example, the mutex is acquired before the condition is checked. Thus, the condition being checked only applies to the current thread. Bye this condition is true, this section of code blocks on the wait call until some other thread performs a single or multiple thread unblock operation on the condition variable.

while loop in the above example is required for two reasons. First, the posix standards do not guarantee the absence of false wakeups (for example, on multiprocessor systems). Second, if another thread changes the condition, it must be rechecked to make sure the change meets the accepted criteria. When a waiting thread blocks, the mutex associated with the condition variable is atomically released by the function pthread_cond_wait() so that another thread can enter a critical section of code.

A thread that performs a single thread unblock will unblock the highest priority thread that is queued on the condition variable. A multiple thread unblock operation unblocks all threads queued on the condition variable. The mutex associated with the condition variable is released by the highest priority atomically unlocked thread. After processing the critical section of code, this thread must release the mutex.

Another kind of condition variable wait operation ( pthread__cond_timedwair()) allows you to set a timeout. At the end of this period, the waiting thread can be unblocked.

barriers

A barrier is a synchronization mechanism that allows you to coordinate the work of several interacting threads so that each of them stops at given point while waiting for other threads before continuing their work.

Unlike the function pthreadjoin(), where a thread is waiting for another thread to complete, the barrier forces threads meet at a certain point. After the specified number of threads reaches the set barrier, all these threads will unblock and continue their work. The barrier is created using the function pthread_barrier_init():

#include

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

As a result of executing this code, a barrier is created at the given address (the pointer to the barrier is in the barrier argument) and with the attributes set by the attr argument. The count argument specifies the number of threads that should call the pthread_barrier_wait() function.

After the barrier is created, each thread calls the pthread_barrier_wait() function, thereby signaling the completion of this action:

#include

int pthread_barrier_wait(pthread_barrier_t "barrier);

When a thread calls a function pthread_barrier_wait(), it blocks until the number of threads that was set by the function pthread_barrier_init(), will not call the function pthread_jbarrier_wait() and, accordingly, will not be blocked. After the specified number of threads call the function pthread_barrier_wait(), they are all unlocked simultaneously.

#include

#include

#include

#include

pthread_barrier_t barrier; // synchronization object of type "barrier"

main() // ignore arguments

time_t now;// create a barrier with counter value 3

pthread_barrier_init(&barrier, NULL, 3); // start two threads - threadl and thread2

pthread_create(NOLL, NOLL, threadl, NULL); // threadl and thread2 are running

pthread_create(NDLL, NDLL, thread2, NDLL); // wait for completion

printf("main() waiting for barrier at %s", ctime (&now));

pthread_barrier_wait (&barrier);// after this point, all three threads are terminated

printf("barrier in mainO done at %s", ctime (&now));

threadl (void *not used)

time(&now); // perform calculations

printf ("threadl starting at %s", ctime (&now)); // pause

pthread_barrier_wait (&barrier) ;// after this point all three threads are terminated

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

thread2 (void *not_used)

time(&now); // perform calculations

printf ("thread2 starting at %s", ctime (&now)); // pause

pthread_barrier_wait(&barrier) ;

// after this point, all three threads are finished

printf ("barrier in thread2() done at %s", ctime (&now));

In the listing example, the main thread creates a barrier, after which it starts counting the number of threads blocked on the barrier for synchronization. IN this case the number of synchronized threads is set to 3: the main() thread, the thread1() thread, and the thread2() thread.

The threads thread1() and thread2() are started. For clarity, a pause is set in the thread to simulate the calculation process. To perform synchronization, the main thread blocks on the barrier and waits for an unlock to occur after the other two threads have not joined it on the barrier.



Waiting for blocking

Sleepon locks work similarly to condition variables, with a few exceptions. As well as condition variables waiting for a lock ( pthread_sleepon_lock()) can be used to block a thread until a condition becomes true (similar to changing the value of a memory location). But unlike condition variables (which must exist for each condition being tested), pending locks are applied to a single .m.tex and a dynamically created condition variable, regardless of the number of conditions being tested. The maximum number of condition variables ends up being maximum number blocked threads.

Top Related Articles