Linux 基本语句_8_C语言_文件控制

为了解决多个进程同时操作一个文件,产生一些情况,通常对文件进行上锁,已解决对共享文件的竞争

对打开文件进行各种操作:

复制代码
int fcentl(int fd, int cmd, .../*arg*/

如果cmd与锁操作有关,那么fcentl函数的第三个参数就要传入一个结构体


其中结构体如下:

c 复制代码
 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) */
               ...
           };


利用fcntl函数解决两个终端同时写访问一个文件产生的竞争问题:

c 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h> 

int lock_set(int fd, int type){
	struct flock old_lock, lock;
	lock.l_whence = SEEK_SET; //加锁区域为文件开始处 
	lock.l_start = 0;//加锁区域在文件位置的相对偏移量 
	lock.l_len = 0;//加锁区域长度 
	lock.l_type = type;//锁的类型 
	lock.l_pid = -1;
	
	fcntl(fd, F_GETLK, &lock);//写入
	
	if(lock.l_type != F_UNLCK){//若未解锁 
	   if(lock.l_type == F_RDLCK){//读取锁 
	   	 printf("Read lock already set by %d\n", lock.l_pid);
	   }
	   else if(lock.l_type == F_WRLCK){
	   	printf("Write lock already set by %d\n", lock.l_pid);
	   } 
	} 
	
	/*上述可能由于不是解锁状态l_type被设置成了相应的锁值下方进行上锁操作时要再次调用type*/ 
	lock.l_type = type;
	
	if((fcntl(fd, F_SETLKW, &lock)) < 0){//上锁失败 
		printf("Lock failed:type  = %d\n", lock.l_type);
		return -1;
	}
	
	switch(lock.l_type){
		case F_RDLCK:
			printf("Read lock set by %d\n", getpid());//获取当前进程的ID
			break;
		case F_WRLCK:
		    printf("Write lock set by %d\n", getpid());
	        break;
		case F_UNLCK:
		    printf("Release lock by %d\n", getpid());//解锁返回1 
			return 1;
			break; 
	}
	
	return 0;//上锁返回0 
}

int main(int argc, const char * argv[]){
	int fd;
	
	if((fd = open("test.txt", O_RDWR)) < 0){
		printf("open error\n");
		return -1;
	}
	
	lock_set(fd, F_WRLCK);//设置写入锁
	getchar();//等待响应 
	lock_set(fd, F_UNLCK);//解锁
	getchar();
	close(fd);
	return 0; 
}

为了更好演示,将写访问改成读访问,读访问可以多进程同时进行:

c 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h> 

int lock_set(int fd, int type){
	struct flock old_lock, lock;
	lock.l_whence = SEEK_SET; //加锁区域为文件开始处 
	lock.l_start = 0;//加锁区域在文件位置的相对偏移量 
	lock.l_len = 0;//加锁区域长度 
	lock.l_type = type;//锁的类型 
	lock.l_pid = -1;
	
	fcntl(fd, F_GETLK, &lock);//写入
	
	if(lock.l_type != F_UNLCK){//若未解锁 
	   if(lock.l_type == F_RDLCK){//读取锁 
	   	 printf("Read lock already set by %d\n", lock.l_pid);
	   }
	   else if(lock.l_type == F_WRLCK){
	   	printf("Write lock already set by %d\n", lock.l_pid);
	   } 
	} 
	
	/*上述可能由于不是解锁状态l_type被设置成了相应的锁值下方进行上锁操作时要再次调用type*/ 
	lock.l_type = type;
	
	if((fcntl(fd, F_SETLKW, &lock)) < 0){//上锁失败 
		printf("Lock failed:type  = %d\n", lock.l_type);
		return -1;
	}
	
	switch(lock.l_type){
		case F_RDLCK:
			printf("Read lock set by %d\n", getpid());//获取当前进程的ID
			break;
		case F_WRLCK:
		    printf("Write lock set by %d\n", getpid());
	        break;
		case F_UNLCK:
		    printf("Release lock by %d\n", getpid());//解锁返回1 
			return 1;
			break; 
	}
	
	return 0;//上锁返回0 
}

int main(int argc, const char * argv[]){
	int fd;
	
	if((fd = open("test.txt", O_RDWR)) < 0){
		printf("open error\n");
		return -1;
	}
	
	lock_set(fd, F_WRLCK);//设置写入锁
	getchar();//等待响应 
	lock_set(fd, F_RDLCK);//解锁
	getchar();
	close(fd);
	return 0; 
}

效果:两进程一起访问

c语言strlen与sizeof函数的区别:

复制代码
char a[32]
a[32] = "abcd";
strlen(a) = 4;
sizeof(a) = 32;
相关推荐
阿让啊16 分钟前
C语言strtol 函数使用方法
c语言·数据结构·c++·单片机·嵌入式硬件
方渐鸿1 小时前
【2024】k8s集群 图文详细 部署安装使用(两万字)
java·运维·容器·kubernetes·k8s·运维开发·持续部署
我爱云计算1 小时前
K8S详解(5万字详细教程)
linux·运维·云原生·容器·kubernetes
明明跟你说过1 小时前
【k8s】资源限制管理:Namespace、Deployment与Pod的实践
运维·docker·云原生·容器·kubernetes·k8s
2301_794333914 小时前
实验室服务器配置|通过Docker实现Linux系统多用户隔离与安全防控
linux·服务器·docker·实验室
Florence234 小时前
计算机组成原理:GPU架构、并行计算、内存层次结构等
c语言
打码人的日常分享4 小时前
运维服务方案,运维巡检方案,运维安全保障方案文件
大数据·运维·安全·word·安全架构
不吃鱼的羊4 小时前
启动文件Startup_vle.c
c语言·开发语言
荣光波比5 小时前
Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装
linux·运维·服务器·nginx·云计算
武文斌775 小时前
单片机:DS18B20测温度、74HC595扩展芯片、8*8LED矩阵
运维·服务器·单片机·嵌入式硬件