濮阳新闻综合频道网站,公司法人变更流程,湖南省建设厅网站官网,wordpress部署到外网所谓原子性操作指的是#xff1a;内核保证某系统调用中的所有步骤#xff08;操作#xff09;作为独立操作而一次性加以执行#xff0c;其间不会被其他进程或线程所中断。 举个通俗点的例子#xff1a;你和女朋友OOXX的时候#xff0c;突然来了个电话#xff0c;势必会打… 所谓原子性操作指的是内核保证某系统调用中的所有步骤操作作为独立操作而一次性加以执行其间不会被其他进程或线程所中断。 举个通俗点的例子你和女朋友OOXX的时候突然来了个电话势必会打断你们高潮的兴致最好的办法就是你们做这事的时候把通讯设备关机就能确保这次的事情很圆满的完成这就是一次原子性操作。 在多进程IO过程中如果操作不具有原子性就可能会导致数据混乱相互覆盖等情况。这种现象也叫竞争状态。 所谓竞争状态指的是操作共享资源的两个进程或线程其结果取决于一个无法预期的顺序因为进程获取的cpu执行时间是不确定的。 1,假想的以独占方式创建一个文件 下面这段代码用open和O_CREAT标志演示一个独占方式创建文件 什么叫独占方式创建文件 就是该进程始终认为这个文件是他打开的或者是他创建的 1 /*2 * Copyright (C) 2018 . All rights reserved.3 * 4 * 文件名称bad_exclusive_open.c5 * 创 建 者ghostwu(吴华)6 * 创建日期2018年01月11日7 * 描 述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文件不存在\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, 结束睡眠\n, getpid() );
37 //其他错误原因导致文件打开失败
38 if( errno ! ENOENT ) {
39 perror( open );
40 exit( -1 );
41 }else {
42 //文件不存在 导致文件打开失败
43 fd open( argv[1], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR );
44 if( fd 0 ) {
45 printf( 文件%s创建失败\n, argv[1] );
46 exit( -1 );
47 }
48 printf( 文件%s,创建并打开成功:fd%d\n, argv[1], fd );
49 printf( 进程id%d\n, getpid() );
50 close( fd );
51 }
52 }else {
53 printf( 文件%s,打开成功:fd%d\n, argv[1], fd );
54 printf( 进程id%d\n, getpid() );
55 close( fd );
56 }
57
58
59 return 0;
60 } View Code 假如我们要创建一个不存在的test.txt文件。 为了演示方便在程序第一次判断文件不存在的情况下让进程挂起( sleep 5 )交出cpu的执行时间这个时候我们可以这样测试两种方法 1在另一个终端登录另一个账户(如root账户)创建test.txt文件 2在另一个终端再开启一个进程 方法一用shell脚本创建一个test.txt并赋予其他组的权限为rw createfile.sh 1 #!/bin/bash
2 #创建文件,并改变权限配合测试
3
4 touch test.txt
5 sudo chmod arw test.txt 实验结果左边的进程依然认为这个文件是他创建并打开的! 方法二在另一个终端再开一个进程测试 两个进程都认为test.txt是他们自己创建并打开的 2如何保证独占方式创建一个文件? 非常简单只需要把加一个标志O_EXCL结合O_CREAT fd open( argv[1], O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR ); 再次按照上面的2种方式测试得到的结果就是 如果在sleep期间别的进程创建了文件那么该进程会报错 3seek与write结合产生相互覆盖 1 /*2 * Copyright (C) 2018 . All rights reserved.3 * 4 * 文件名称seek_file.c5 * 创 建 者ghostwu(吴华)6 * 创建日期2018年01月11日7 * 描 述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 BUFSIZE
21 #define BUFSIZE 50
22 #endif
23
24
25 int main(int argc, char *argv[])
26 {
27 if( argc 3 || strcmp( argv[1], --help ) 0 ) {
28 printf( usage:%s filename wstring\n, argv[1] );
29 exit( -1 );
30 }
31
32 if( argv[2][0] ! w ) {
33 printf( 必须以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( 文件%s打开失败\n, argv[1] );
42 exit( -1 );
43 }
44
45 if ( -1 lseek( fd, 0, SEEK_END ) ) {
46 printf( 指针移动到尾部失败\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( 文件写入失败\n );
60 exit( -1 );
61 }
62 printf( pid%d,向文件%s写入了%ld个字节\n, getpid(), argv[1], nwrite );
63
64 return 0;
65 } View Code 如果第一个进程执行到seek与write之间交出 cpu, 被执行相同代码的第二个进程中断那么这两个进程在写入数据前都把指针移动到相同的位置如果一个进程先完成那么后一个进程会覆盖前面进程写入的数据 试验结果 第二个进程后结束 第一个进程写入的123被第二个进程的4567覆盖产生结果 4567 第一个进程后结束第一个进程写入的4567被第二个进程的123覆盖产生结果 1237 如何避免数据覆盖打开文件时候加入O_APPEND标志 fd open( argv[1], O_RDWR | O_APPEND ); 总结 1理解原子性操作 2理解标志O_CREAT与O_EXCL结合的意义 3理解O_APPEND标志 4理解竞争状态 转载于:https://www.cnblogs.com/ghostwu/p/8267634.html