BUFFERS, PIPE, DEVICE AND PROGRAM MANAGEMENT.pptx

JohnNderi1 6 views 32 slides Aug 16, 2024
Slide 1
Slide 1 of 32
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32

About This Presentation

BUFFERS, PIPE, DEVICE AND PROGRAM MANAGEMENT


Slide Content

Buffering File Operations A buffer is a temporary storage between the sender and receiver of bytes on a stream. The buffer is an additional piece of memory location that is used to moderate the flow of bytes from the source to the destination. A buffer is useful in a variety of situations: When the sender puts bytes into a stream faster than the receiver can handle. If a program is in a middle of an operation and is not prepared to receive any byte. The buffer can store up the bytes until the program is able to handle them, receiving them either at a reduced rate or when it is ready for them. 3/20/2024 1

Buffering File Operations There are three basic types of buffering: Block buffering Line buffering And unbuffered They differ in how the temporary storage is flushed . Flushing is the act of emptying out the temporary storage, sending all the bytes in the buffer on down the stream to the receiver. In a block buffer, fixed-size chunk of memory is filled before being passed on to the receiver. In a line buffer, any bytes inside the buffer are sent to the receiver once a newline character (byte value of 13) is received. Finally, if the stream is unbuffered, then each byte is sent to the receiver as soon as it is placed in the buffer. 3/20/2024 2

Buffering File Operations Once you have opened a file, you can control how input operations are buffered by calling setvbuf (), which has the following prototype : The first parameter is the file pointer to an open file. You can only call setvbuf () to determine the buffering before you have performed any other operation with the file pointed to by the first argument. The second parameter specifies an array that is to be used for buffering, and the fourth parameter is the size of the array. If you specify NULL as the second argument, setvbuf () will allocate a buffer for you with the size you specify as the fourth argument . int setvbuf (FILE * restrict pfile , char * restrict buffer, int mode, size_t size); 3/20/2024 3

Buffering File Operations The third argument specifies the buffering mode and can be one of the following : _IOFBF causes the file to be fully buffered. When input and output is fully buffered, data are written or read in blocks of arbitrary size . _IOLBF causes operations to be line buffered. When input and output is line buffered, data are written or read in blocks terminated by a newline . _IONBF causes input and output to be unbuffered. With unbuffered input and output, data are transferred character by character. This is extremely inefficient, so you would only use this mode when it was essential. 3/20/2024 4

Buffering File Operations The setvbuf () returns 0 when everything is okay and a nonzero integer when it isn’t. Here’s how you might use it for a file pointed to by pfile : If you just want full buffering for input or output, you can call setbuf (), which has this prototype: The first parameter is the file pointer and the second is the address of an array to be used as a buffer. The second argument can be NULL, which I recommend, in which case the buffer will be created for you. If you specify buffer, its length must be BUFSIZ bytes, where BUFSIZ is defined in stdio.h . size_t bufsize = 1024; if( setvbuf ( pfile , NULL, _IOFBF, bufsize )) printf_s ("File buffering failed!\n"); void setbuf (FILE * restrict pfile , char * restrict buffer); 3/20/2024 5

Buffering File Operations Here’s how you might buffer operations for a file with the pointer pfile using your own buffer : Note that you must ensure that your buffer continues to exist as long as the file is open. This implies that you must take great care when you use an automatic array that will expire at the end of the block in which you create it. If the second argument to setbuf () is NULL, the file operations will not be buffered . char * buf = malloc (BUFSIZ); setbuf ( pfile , buf ); 3/20/2024 6

Buffering File Operations Block buffering is commonly used for large data transfers, such as file I/O. It makes the transfer more efficient by saving up a large number of bytes before actually transporting them. If a program is doing a lot of large data transfers, block buffering will speed it up. Line buffering is typically used for text-based I/O, such as when interacting with a user. It allows bytes to be modified before actually committing them to the stream transport . For example, a delete or backspace key can be used to modify the bytes in the line buffer, while the enter key can be used to initiate the flush.

EXAMPLE Finally, buffering may be completely turned off when responsiveness is critical. For example, a program may want to take action after any keypress provided by the user, without having to wait for flushing. In this case , the input stream would likely be unbuffered . The effect of buffering can be seen through the following C code: #include <stdio.h> main() { int i; for (i=0; i<5; i++) { printf("i=%d ",i); sleep(1); } }

Executing this code, no output is seen until the program ends, which is 5 seconds after it started. This means that the stdout stream is buffered, either block or line . The type of buffering can be determined by modifying the printf (), adding a newline at the end, as follows: printf (" i =%d\n", i ); /* add newline */ Executing the code with this modification, a new line of output is seen once per second. This indicates that the stream is line buffered. The buffer can also be forced to flush using the fflush () function call, as follows: printf (" i =%d ", i ); fflush ( stdout ); /* force flushing of the buffer */

Executing the code with this modification, a new line of output is seen once per second . This indicates that the stream is line buffered. The buffer can also be forced to flush using the fflush () function call, as follows: printf (" i =%d ", i ); fflush ( stdout ); /* force flushing of the buffer */ By calling fflush (), the program does not have to print a newline character each time the buffer is to be flushed. Note that fflush () can be used on any stream, not just the stdout stream, and it can be used to flush streams that are either block or line buffered.

PIPES Pipes is a connection between two processes, such that the standard output from one process becomes the standard input of the other process. In UNIX Operating System, Pipes are useful for communication between related processes(inter-process communication (IPC)). Pipe is one-way communication only i.e we can use a pipe such that One process write to the pipe, and the other process reads from the pipe. It opens a pipe, which is an area of main memory that is treated as a  “virtual file” . The pipe can be used by the creating process, as well as all its child processes, for reading and writing. One process can write to this “virtual file” or pipe and another related process can read from it. If a process tries to read before something is written to the pipe, the process is suspended until something is written. The pipe system call finds the first two available positions in the process’s open file table and allocates them for the read and write ends of the pipe.

PIPES Pipes behave  FIFO (First in First out), Pipe behave like   queue  data structure. Size of read and write don’t have to match here. We can write   512  bytes at a time but we can read only 1 byte at a time in a pipe.

PIPES EXAMPLES #include < stdio.h > int main () { int x,s ; s=0; while (1) { printf ("#? "); scanf ("% d",&x ); if (x == 0) break; s= s+x ; printf (" sum=%d\ n",s ); } }

PIPE CHANING This code prompts the user for integers, reporting the sum as each new number is entered. It exits when a value of zero is entered. Now suppose we create a file named input1.txt that contains the following: 4 1 7

Common shell symbols

PIPE CHAINING This is the exact same sequence of bytes that was input through the keyboard to the program. The < symbol allows the user to redirect the stdin stream to a file instead of the keyboard. ./ testp2 > mtano.txt Running the program in this manner, the user provides input to the program from the file mtano.txt instead of from the keyboard. In fact, the program is disconnected from the keyboard. Nothing the user types would be sent to the program; instead, it would be buffered until the program ended, and then sent to the shell. Note also that the bytes being sent to the program from the file are not being displayed. This is because they are not coming from the keyboard, which automatically echoes (copies) its bytes to the stdout stream.

PIPE CHAINING The stdout stream can be treated similarly. The > symbol allows the user to redirect the stdout stream to a file instead of to the display. ./testp2 < mtano.txt | > mts.txt Running the program in this manner, the program provides output to the file mts.txt instead of to the terminal display. In this case, we can see the input bytes being typed at the keyboard, but we see none of the output

Finally, we can connect the stdout stream of one program to the stdin stream of a second program. In order to demonstrate, we will make use of the following additional code:

DEVICES AND DEVICE DRIVERS One of the neat aspects of Unix is that any peripheral, device, or piece of hardware connected to the computing system can be accessed as though it were a file. This concept is often referred to as “file-based I/O.” An I/O transaction with a device is handled similarly to an I/O transaction with a file. They both make use of streams and buffers, and they both use the same I/O functions.

DEVICE DRIVERS A device driver is a set of functions used to access a device. These functions include custom versions of open(), close(), read(), write(), seek(), and a small handful of others. The functions associated with a particular device are executed when the device is accessed through its device filename. Determining which functions to execute is controlled by something called the major device number . The major device number of a particular device filename can be seen by looking at the full file information for the given filename.

Linux Approach to Device Drivers: Unlike Windows, where devices and drivers are managed through a centralized console called the Device Manager, Linux treats hardware devices as ordinary files. When a device is connected to the system, a corresponding device file is created in the /dev directory. Two common types of devices in Linux: Character devices : These devices transmit data character by character (e.g., mouse, keyboards). Block devices: These devices transfer data in blocks (e.g., USB drives, hard drives, CD-ROMs). Device files are accessed just like regular files, making it easier for software to interact with the device drivers

Examples of Device Files: Character devices: /dev/consoles or /dev/ttyS0: Accessed as a stream of bytes. Block devices: /dev/ sda , /dev/ sdb , etc.: Represent mass storage devices like memory sticks and hard drives. The alphabetical order indicates the order in which the computer detected these devices. Pseudo devices: These act as device drivers without an actual physical device. Examples include /dev/null, /dev/zero, and /dev/pf2.

Useful Commands for Device Management: fdisk : Displays partitions on a disk and file system-related details. Example: sudo fdisk -l sfdisk : Shows partition information, including partition sizes. parted: Lists and modifies disk partitions. Example: sudo parted -l df : Displays file system details. Use grep to filter real hard disk files. Example: df -h | grep ^/dev lsblk : Provides details about block devices. inxi : Lists hardware components in the file system. Example: inxi -D -xx

Question ? A systems programmer has been tasked to assist in development of flight control software to support such a delicate function. Discuss appropriate the steps that will convert the source version from C/C++ of such Flight Software program into a runnable version of the functional software that it represents.

PROGRAM MANAGEMENT Program management concerns the organization, building, and distribution of programs. The organization of a program involves how the code is written, including its logical and visual layout. The goals of good organization include code readability and modularity . These characteristics support good design practices and make program debugging and scaling easier. The building of a program entails how the code is compiled. Compiling involves many intermediate steps and file types that enable the construction of an executable. The distribution of a program is concerned with how the code is packaged and delivered to target systems . There are a number of tools and practices designed to facilitate program distribution and installation.

PROGRAM BUILDING After a program is written, it must be built into an executable so that it can be run. Building a program consists of a series of steps. At each step, the code is transformed to produce an intermediate form . Intermediate forms include preprocessed, assembly code, object code, and libraries. Understanding these steps and the intermediate forms is important for several reasons. Each offers different strategies for saving programming time or maximizing system resources. For example , the preprocessing step provides macros for repetitive string substitution; the assembly step provides a programmer with named memory locations ; and the linking step provides a way to reuse existing executable code in multiple programs . The intermediate forms can be retained between program builds to speed up subsequent rebuilds. Errors in the program can be uncovered at each program building step .

Object Code and Linking An object code file contains machine code , instructions that can be run on the processor. But an object code file cannot be directly executed. Object code files must be linked to become an executable program that can be run. Linking is the process of bringing together multiple pieces of object code and arranging them into an executable . Object code can come from multiple source code files, each compiled into its own object code file .

Linking When compiling multiple files, it is often convenient to instruct the compiler to keep object code files , so that only changed source code files need to be recompiled. Everything else needs only to be linked. This can save time when the number of source code files comprising a program grows large. It can also help with organization , in that it helps track which files have had modifications made to them between program builds

Linking primarily serves to bring together object code files into an executable. However , it can also bring in object code from library files. Figure 6.2 shows this in diagram form . Library files contain object code for functions that are frequently used. In this way, the source code can be compiled once and stored in a permanent place, ready to link . For example, the most commonly linked library file is libc.a , the primary library file of the C standard library. It contains the object code for the standard functions like printf (), fopen (), and strcmp ().

COMPILING The first step is preprocessing. Preprocessing provides mechanisms to support text substitutions, also called macros or macro substitutions. The second step in the compilation process is the actual compiling, which converts the C source code into assembly code. Once again, the gcc compiler can be instructed to stop at this point.

The third and final step in the compilation process is called assembling. During this step, assembly code is translated into machine code to get it ready to run . Assembly code is a human-readable version of machine code, much like ASCII symbols are a human-readable version of byte values. (Imagine trying to read text looking at the raw byte values.) Each machine code instruction is actually a set of byte values telling the processor what to do. The assembly instruction is a human-readable translation of those byte values.

Answer to the question Step 1-Create Source File Step 2- Compiles the source file-The compilation is the process of converting high-level language instructions into low-level language instructions. Step 3-After completing compilation successfully, an executable file is created with a .exe extension. The processor can understand this .exe file content so that it can perform the task specified in the source file. Lexical Analysis, Syntax Analysis Code Generation Check the results displayed on the screen/output
Tags