Basic Article 2: apue chap14 advanced I/O

Source: Internet
Author: User
Tags flock
0. preface this article describes the content involved in the ngx_process_events_and_timers function in nginx. I learned
14.2 non-blocking I/o14.3 record locks 14.7readv and writev Functions
The record lock is used for the accept mutex in nginx.

14.1 Introduction

14.2 non-blocking I/OIn the dormitory, student a lives in room 617. B from an external school told student a to visit student a in advance, but did not tell student a time, at the same time, student A did not inform student B of his dormitory number. In order to be able to receive B, student a can choose from the following methods: 1) Keep waiting for student B at the dormitory door; 2) Check whether student B is there at intervals, if student A does not arrive, he will return to the dormitory and do other things. 3) When student B arrives, Aunt su will lead student B to look for student a one by one. 4) When student B arrives, the boarding manager informs B of some information about student A. Student B goes to student A by himself. In this example, student A is a process, and student B is an event to be handled. Select 1) blocking; 2) non-blocking; 3) Select select/poll type; 4) epoll type non-blocking I/O: we can call I/O operations such as open, read, and write, and these operations will never be blocked. When a FD is set to non-blocking, the process sends an I/O operation to This FD. If there is data, the process processes it; if there is no data, an error is returned immediately.
/* Chap14 14-1 long non-blocking write p357
Filename: chap14_1.c */
# Include <stdio. h>
# Include <unistd. h>
# Include <sys/types. h>
# Include <fcntl. h>
# Include <stdlib. h>
Void set_fl (int fd, int flags)
{
Int val;
If (val = fcntl (FD, f_getfl, 0) <0)
Printf ("fcntl error \ n ");
Val | = flags;
If (fcntl (FD, f_setfl, Val) <0)
Printf ("fcntl error \ n ");
}
Void clr_fl (int fd, int flags)
{
Int val;
If (val = fcntl (FD, f_getfl, 0) <0)
Printf ("fcntl error \ n ");
Val & = ~ Flags;
If (fcntl (FD, f_setfl, Val) <0)
Printf ("fcntl error \ n ");
}

Char Buf [50];

Int main (void)
{

Int ntowrite, nwrite;
Char * PTR;
Ntowrite = read (stdin_fileno, Buf, sizeof (BUF ));
Printf ("read % d bytes \ n", ntowrite );
/* Set non-block */
// Fcntl (stdin_fileno, f_setfl, (fcntl (stdin_fileno, f_getfl, 0) | = o_nonblock ));
Set_fl (stdout_fileno, o_nonblock );
PTR = Buf;
While (ntowrite> 0 ){
Nwrite = write (stdout_fileno, PTR, ntowrite );
Printf ("write % d \ n", nwrite );
If (nwrite> 0 ){
PTR + = nwrite;
Ntowrite-= nwrite;
}
}/* While */
Clr_fl (stdout_fileno, o_nonblock );
Exit (0 );
}

The operation failed to get the result from the book.
14.3 record lockThe record lock, which is called the byte range lock, is used to lock a certain area of the file. When a process is reading or modifying a part of a file, it can prevent other processes from modifying this part. Record lock: when a process is reading or modifying a part of a file, record lock can prevent other processes from modifying the same file area. Record is a misuse because the Unix kernel does not use the file record concept at all. The more appropriate term is the byte-range locking, because it only locks a region in the file (or the entire file ). 1. History 2. fcntl record lock
# Include <fcntl. h>
Int fcntl (INT fileds, int cmd,.../* struct flock * flockptr */);
Parameter: For record locks, the CMD parameter is f_setlk, f_setlkw, and f_getlk, which are set, clear, and check record locks respectively.
For record locks, the third parameter is a struct:
Struct flock {
...
Short l_type;/* type of lock: f_rdlck, f_wrlck, f_unlck */
Short l_whence;/* how to interpret l_start: seek_set, seek_cur, seek_end */
Off_t l_start;/* Starting offset for Lock */
Off_t l_len;/* number of bytes to lock */
Pid_t l_pid;/* PID of process blocking our lock (f_getlk only )*/
...
};
The member variables l_whence, l_start, and l_len specify the specific byte range we want to lock.
To lock the entire file, we set Rochelle start and Rochelle where to make the starting point of the lock at the beginning of the file, and the length of Rochelle Len is 0. That is, Rochelle start is set to 0, and Rochelle whence is set to seek_set.
Example:
Ngx_err_t

Ngx_trylock_fd (ngx_fd_t FD)
{
Struct flock FL;

Ngx_memzero (& FL, sizeof (struct flock ));
Fl. l_type = f_wrlck;
Fl. l_whence = seek_set;

If (fcntl (FD, f_setlk, & FL) =-1){
Return ngx_errno;
}

Return 0;
}

Deadlock:If the two processes wait for each other to hold and lock the resources, the two processes are in a deadlock state. If a process has controlled one lock area in the file and then tries to lock the area controlled by another process, it will sleep. In this case, there is a possibility of a deadlock. 3. Implicit inheritance and release of locks there are three rules for automatic inheritance and release of record locks. 1) locks are related to processes and files. There are two meanings: 1. when a process is terminated, all the locks it creates are released; 2. when a descriptor is disabled at any time, a lock on the file that the process can reference through this descriptor is released (these locks are set by the process ). This means that if the following four steps are performed: After fd2 is disabled, the lock set on fd1 is released. When multiple FD points to the same file and one FD is disabled, all locks on the file will be released.
Fd1 = open (pathname ,....)
Read_lock (fd1 ,...);
Fd2 = DUP (fd1); // fd2 = open (pathname ,.....)
Close (fd2 );
2) The child process generated by fork does not inherit the lock set by the parent process. Think about it as well. People record the lock to prevent multiple processes from accessing the same file area. Your parent process is locked, and the child process is locked. Isn't it accessible to both parent and child processes. 3) After exec is executed, the new program can inherit the lock of the original execution program. However, if the close-on-exec identifier is set for a file descriptor, all the locks of the corresponding file are released when the file descriptor is closed as part of exec. 4. Implementation of FreeBSD 5. Apply a lock to the end of the file 6. Create a lock and a mandatory lock

14.4 streams System V Stream Mechanism14.5i/o multiplexing14.6 asynchronous I/O14.7readv and writev Functions

Struct iovec {void * iov_base; size_t iov_len ;}
Writev and readv
Function prototype
# Include <sys/uio. h>

Ssize_t readv (int fd, const struct iovec * IOV, int iovcnt );

Ssize_t writev (int fd, const struct iovec * IOV, int iovcnt );
Function: read or write data in multiple buffers.
Returned value: Number of transmitted bytes.-1 is returned if an error occurs.

Description: stores multiple data together and writes data residing in two or more unconnected buffers at a time.
Using writev, you can specify a series of buffers to collect the data to be written, so that you can save the data in multiple buffers and write it out at the same time, this prevents the interaction between Nagle and delayed ack algorithms.
Example: # include <stdio. h> # include <unistd. h> # include <string. h> # include <sys/uio. h> int main (void) {struct iovec IOV [3]; int Len; char * buf1 = "123"; char * buf2 = "456 "; char * buf3 = "7890"; Len = 0; IOV [0]. iov_base = buf1; IOV [0]. iov_len = strlen (buf1); IOV [1]. iov_base = buf2; IOV [1]. iov_len = strlen (buf2); IOV [2]. iov_base = buf3; IOV [2]. iov_len = strlen (buf3); Len = Len + IOV [0]. iov_len + IOV [1]. iov_len + IOV [2]. iov_len; If (writev (stdout_fileno, IOV, 3) =-1) {printf ("writev error \ n");} return 0 ;}

/* Test Case 2: This test case is about writev in apue chap17.5 Open Server Version 1 */
# Include <stdio. h>
# Include <unistd. h>
# Include <string. h>
# Include <sys/uio. h>

# Define cl_open "open"
Int main (void)
{
Char * buf2 = "456 ";
Char * buf3 = "789 ";
Struct iovec IOV [3];
IOV [0]. iov_base = cl_open "";
IOV [0]. iov_len = strlen (cl_open) + 1;

IOV [1]. iov_base = buf2;
IOV [1]. iov_len = strlen (buf2 );

IOV [2]. iov_base = buf3;
IOV [2]. iov_len = strlen (buf3 );
 

If (writev (stdout_fileno, IOV, 3) =-1 ){
Printf ("writev error \ n ");
}
Return 0;
}

Running result:
Open456789
If you change IOV [0]. iov_base = cl_open ""; to IOV [0]. iov_base = cl_open;
The running result is open456789.

14.8 readn and writen Functions14.9 storage ing I/OStorage ing I/O (memory-mapped I/O): maps a disk file to a buffer in the bucket. When data is retrieved from the buffer zone, it is equivalent to reading the corresponding bytes in the file. when data is written to the buffer zone, the corresponding bytes are automatically written to the file. In this way, I/O can be executed without read and write.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.