Linux system programming: atomic operation experiment in the IO read/write process, linuxio

Source: Internet
Author: User

Linux system programming: atomic operation experiment in the IO read/write process, linuxio

The so-called atomic operation means that the kernel ensures that all steps (Operations) in a system call are executed as independent operations at one time without being interrupted by other processes or threads.

For example, when you and your girlfriend OOXX have a sudden call, they will inevitably interrupt your climax. The best way is, when you do this, by shutting down the communication device, we can ensure that this operation is completed successfully. This is an atomic operation.

In multi-process I/O processes, operations that are not atomic may cause data confusion and mutual coverage. This phenomenon is also called competition.

The so-called competition state means that the results of two processes (or threads) operating on shared resources depend on an unexpected order, because the cpu execution time obtained by the process is uncertain.

1. Create a file exclusively.

The following code uses the open and O_CREAT signs to demonstrate how to create an exclusive file. What is exclusive file creation? That is, the process always thinks that the file is opened by him or created by him.

1/* ============================================== =========================================== 2 * Copyright (C) 2018. all rights reserved. 3*4 * file name: bad_exclusive_open.c 5 * Creator: ghostwu (Wu Hua) 6 * creation Date: July 7 * description: 8*9 ============================================ ================== */10 11 # include <stdio. h> 12 # include <sys/types. h> 13 # include <sys/stat. h> 14 # include <fcntl. h> 15 # include <stdlib. h> 16 # include <String. h> 17 # include <sys/types. h> 18 # include <unistd. h> 19 # include <errno. h> 20 21 22 int main (int argc, char * argv []) 23 {24 if (argc <2 | strcmp (argv [1], "-- help ") = 0) {25 printf ("usage: % s filename \ n", argv [0]); 26 exit (-1 ); 27} 28 29 printf ("pid = % d, % s file does not exist \ n", getpid (), argv [1]); 30 31 int fd =-1; 32 33 fd = open (argv [1], O_WRONLY); 34 if (fd <0) {35 sleep (5); 36 printf ("pid = % d, end Bundle sleep \ n ", getpid (); 37 // other error causes, resulting in file opening failure 38 if (errno! = ENOENT) {39 perror ("open"); 40 exit (-1 ); 41} else {42 // file opening failed because the file does not exist 43 fd = open (argv [1], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 44 if (fd <0) {45 printf ("file % s creation failed \ n", argv [1]); 46 exit (-1); 47} 48 printf ("file % s, created and opened successfully: fd = % d \ n ", argv [1], fd); 49 printf (" process id = % d \ n ", getpid ()); 50 close (fd); 51} 52} else {53 printf ("file % s, opened successfully: fd = % d \ n", argv [1], fd ); 54 printf ("process id = % d \ n", getpid (); 55 close (fd); 56} 57 58 59 return 0; 60}View Code

Assume that we want to create an existing test.txt file.

For demonstration convenience, when the program first determines that the file does not exist, let the process suspend (sleep 5) to hand over the cpu execution time. At this time, we can test the following two methods:

1. Create the test.txt file for another account (for example, rootaccount)

2. Start another process on another terminal.

Method 1: Create a test.txt with the shellscript and grant the rw permission to other groups.

Createfile. sh

1 #! /Bin/bash2 # create a file and change the permission to test 3 4 touch test.txt 5 sudo chmod a + rw test.txt

Experiment results: the process on the left still thinks this file was created and opened by him!

Method 2: Test another process on another terminal

Test.txt is created and opened by themselves.

2. How can I create a file exclusively?

It is very simple, just add a flag O_EXCL, combined with O_CREAT

fd = open( argv[1], O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR );

Test again according to the above two methods. The result is:

If another process creates a file during sleep, the process reports an error.

3. seek and write are combined to generate mutual coverage1/* ============================================== =========================================== 2 * Copyright (C) 2018. all rights reserved. 3*4 * file name: seek_file.c 5 * Creator: ghostwu (Wu Hua) 6 * creation Date: July 6, January 11, 2018 7 * description: 8*9 ============================================ ================== */10 11 # include <stdio. h> 12 # include <stdlib. h> 13 # include <string. h> 14 # include <sys/types. h> 15 # include <sys/stat. h> 16 # include <fcntl. h> 17 # include <sys/types. h> 18 # include <unistd. h> 19 20 # ifndef BUFSIZE21 # define BUFSIZE 5022 # endif23 24 25 int main (int argc, char * argv []) 26 {27 if (argc <3 | strcmp (argv [1], "-- help") = 0) {28 printf ("usage: % s filename w <string> \ n ", argv [1]); 29 exit (-1); 30} 31 32 if (argv [2] [0]! = 'W') {33 printf ("must start with w \ n"); 34 exit (-1); 35} 36 37 int fd =-1; 38 fd = open (argv [1], O_RDWR); 39 40 if (fd <0) {41 printf ("file % s opening failed \ n ", argv [1]); 42 exit (-1); 43} 44 45 if (-1 = lseek (fd, 0, SEEK_END )) {46 printf ("failed to move pointer to tail \ n"); 47 exit (-1); 48} 49 50 sleep (5); 51 52 char buf [BUFSIZE]; 53 ssize_t nwrite; 54 55 strcpy (buf, & argv [2] [1]); 56 57 nwrite = write (fd, buf, strlen (buf )); 58 if (-1 = nwrite) {59 printf ("file write failed \ n"); 60 exit (-1); 61} 62 printf ("pid = % d, % ld bytes \ n ", getpid (), argv [1], nwrite); 63 64 return 0; 65} are written to the file % s}View Code

If the first process is executed between seek and write, the cpu is handed over, and the second process that executes the same code is interrupted, the two processes move the pointer to the same position before writing data, if a process is completed first, the latter process will overwrite the data written by the previous process.

Test results:

End after the second process: 123 written by the first process is overwritten by 4567 of the second process, resulting in 4567

End after the first process: 4567 written to the first process is overwritten by 123 of the second process, and result 1237 is generated.

How to avoid data coverage? When opening the file, add the O_APPEND flag

fd = open( argv[1], O_RDWR | O_APPEND );

 

 

Summary:

1) understand atomic operations

2) understand the significance of the combination of O_CREAT and O_EXCL

3) understand the O_APPEND flag

4) understand the competition status

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.