Linux中一个关于while循环里文件操作close的一个问题

最近在做一个文件存储功能时遇到的一个问题。在while(1)死循环中open文件,修改里面的数据。close在while外。当注释掉这close时,当终止程序时并不会保存已修改的数据。反之则会保存。不多说直接按上代码。

static gpointer wort_thread(gpointer data)
{
    
      
	int fd;
   	int ret;
   	int i=0;
   	int nbytes;
   	struct msghdr msg;
   	struct ifreq ifr;
   	fd_set rdfs;

	struct sockaddr_can addr;
	DisPlayData* disdata=(DisPlayData*)data;
	GstElement *png_overlay = GST_PAD_PARENT (disdata->pad_png);
	GstElement *text_overlay = GST_PAD_PARENT (disdata->pad_text);
	fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
	addr.can_family = AF_CAN;
	memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
	strncpy(ifr.ifr_name, "can0", strlen("can0"));

    if(ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
    
    
				perror("SIOCGIFINDEX");
				exit(1);
			}

    addr.can_ifindex = ifr.ifr_ifindex;
    setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));

    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    
    
			perror("bind");
			return NULL;
	  }
		/* set rfilter */		
	struct can_filter rfilter;
	rfilter.can_id = 0x1d5d0002;
	rfilter.can_mask = 0x1fffffff;
	setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

	iov.iov_base = &canframe;
	msg.msg_name = &addr;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = &ctrlmsg;
    
    int x, y;
    gchar x_pal1_fd, y_pal1_fd, x_pal2_fd, y_pal2_fd, x_camlink_fd, y_camlink_fd; 
	gchar xbuf[4], ybuf[4];
	gchar flag_png = 1;
	gchar flag_text = 1; 
	gchar channel = 0x10; // 初始通道 pal1 = 0x10

    if((x_pal1_fd = open("x1.txt",O_RDWR|O_CREAT))< 0){
    
    
      perror("open");
    }
    if((y_pal1_fd = open("y1.txt",O_RDWR|O_CREAT))< 0){
    
    
      perror("open");
    }
    if( (read(x_pal1_fd, xbuf, 4) && read(y_pal1_fd, ybuf, 4)) == 0){
    
    
      perror("read or write");
    }
    x = atoi(xbuf);
    y = atoi(ybuf);
    g_object_set (png_overlay, "offset-x", x, "offset-y", y, NULL);
	set_enum_property_by_name (text_overlay, "valignment", "top");
  	set_enum_property_by_name (text_overlay, "halignment", "left");
  	set_enum_property_by_name (text_overlay, "line-alignment", "left");

    while(1)
   	{
    
    
     	FD_ZERO(&rdfs);
		FD_SET(fd, &rdfs);
		if((ret = select(fd+1, &rdfs, NULL, NULL, NULL)) <= 0) {
    
    
			perror("select");
			continue;
		}
		if(FD_ISSET(fd, &rdfs))
		{
    
    
   		iov.iov_len = sizeof(canframe);
		msg.msg_namelen = sizeof(addr);
		msg.msg_controllen = sizeof(ctrlmsg);  
		msg.msg_flags = 0;
		nbytes = recvmsg(fd, &msg, 0);
/*
			g_print("nbytes %d \r\n",nbytes);
			g_print("canframe.can_id%d:",canframe.can_id);

			for(i=0;i<8;i++){
				g_print("%02X ",canframe.data[i]);
			}
*/	
		switch(canframe.data[0]){
    
    				
        	case 0x01:
				if(x <= MAX_W){
    
    
					g_object_set (png_overlay, "offset-x", ++x, "offset-y", y, NULL);
					memset(xbuf, 0, 4);
		        	sprintf(xbuf, "%d", x);
					if(channel == 0x12){
    
    
						lseek(x_camlink_fd, 0, SEEK_SET); 
					  	write(x_camlink_fd, xbuf, 4);
					}
					if(channel == 0x10){
    
    
						lseek(x_pal1_fd, 0, SEEK_SET);
			      		write(x_pal1_fd, xbuf, 4);
					}
					if(channel == 0x11){
    
    
						lseek(x_pal2_fd, 0, SEEK_SET);
			      		write(x_pal2_fd, xbuf, 4);
					}				
				}		break;         
		    case 0x02:
				if(x > 0){
    
    
			 	  	g_object_set (png_overlay, "offset-x", --x, "offset-y", y, NULL);
					memset(xbuf, 0, 4);
	        		sprintf(xbuf, "%d", x); 
					if(channel == 0x12){
    
    
						lseek(x_camlink_fd, 0, SEEK_SET); 
						write(x_camlink_fd, xbuf, 4);
					}
					if(channel == 0x10){
    
    
						lseek(x_pal1_fd, 0, SEEK_SET);
				      	write(x_pal1_fd, xbuf, 4);
					}
					if(channel == 0x11){
    
    
						lseek(x_pal2_fd, 0, SEEK_SET);
				      	write(x_pal2_fd, xbuf, 4);
					}				
				}		break;
         	case 0x03:
				if(y <= MAX_H){
    
    
		       	 	g_object_set (png_overlay, "offset-x", x, "offset-y", ++y, NULL);
					memset(ybuf, 0, 4);
	        		sprintf(ybuf, "%d", y);
					if(channel == 0x12){
    
    
						lseek(y_camlink_fd, 0, SEEK_SET); 
			      		write(y_camlink_fd, ybuf, 4);
					}
					if(channel == 0x10){
    
    
						lseek(y_pal1_fd, 0, SEEK_SET);
			      		write(y_pal1_fd, ybuf, 4);
					}
					if(channel == 0x11){
    
    
						lseek(y_pal2_fd, 0, SEEK_SET);
			      		write(y_pal2_fd, ybuf, 4);
					}				
				}		break;
         	case 0x04:
				if(y > 0){
    
    
		        	g_object_set (png_overlay, "offset-x", x, "offset-y", --y, NULL);
					memset(ybuf, 0, 4);
		        	sprintf(ybuf, "%d", y); 
					if(channel == 0x12){
    
    
						lseek(y_camlink_fd, 0, SEEK_SET);
				      	write(y_camlink_fd, ybuf, 4);	
					}
					if(channel == 0x10){
    
    
						lseek(y_pal1_fd, 0, SEEK_SET);
				      	write(y_pal1_fd, ybuf, 4);
					}
					if(channel == 0x11){
    
    
						lseek(y_pal2_fd, 0, SEEK_SET);
				      	write(y_pal2_fd, ybuf, 4);
					}				
				}		break;
			case 0x0d:
				if(flag_png == 1){
    
    
	   	  			g_object_set (png_overlay, "location","asert.png",NULL);
					flag_png = 0;
				}break;

 			case 0x0e:
				if(flag_png == 0){
    
    
	   	  			g_object_set (png_overlay, "location","asert1.png",NULL);		
					flag_png = 1;
				}break;
			case 0x0f:
				if(flag_text == 1){
    
        
					g_object_set (text_overlay, "text","",NULL);
					flag_text = 0;
				}break;

  /* Switch video lines */	

         	case 0x10:
				close(x_pal2_fd);
		        close(y_pal2_fd);
		        close(x_camlink_fd);
		        close(y_camlink_fd);
				if((x_pal1_fd = open("x1.txt",O_RDWR|O_CREAT))< 0){
    
    
					perror("open");
				}
				if((y_pal1_fd = open("y1.txt",O_RDWR|O_CREAT))< 0){
    
    
					perror("open");
					return NULL;
				}
				memset(xbuf, 0, 4);
				memset(ybuf, 0, 4);
				if((read(x_pal1_fd, xbuf, 4) || read(y_pal1_fd, ybuf, 4)) == 0){
    
    
					perror("read or write");
				}
				x = atoi(xbuf);
				y = atoi(ybuf);
				g_object_set (png_overlay, "offset-x", x, "offset-y", y, NULL);
				g_object_set (text_overlay, "text","电视大", "font-desc","Sans, 20", "halignment","left", 
											"valignment","top", "line-alignment","center",NULL);
				flag_text = 1; channel = 0x10; break;

        	case 0x11:
		         close(x_pal1_fd);
		         close(y_pal1_fd);
		         close(x_camlink_fd);
		         close(y_camlink_fd);
				if((x_pal2_fd = open("x2.txt",O_RDWR|O_CREAT))< 0){
    
    
					perror("open");
				}
				if((y_pal1_fd = open("y2.txt",O_RDWR|O_CREAT))< 0){
    
    
					perror("open");
				}
				memset(xbuf, 0, 4);
				memset(ybuf, 0, 4);
				if((read(x_pal2_fd, xbuf, 4) || read(y_pal2_fd, ybuf, 4)) == 0){
    
    
					perror("read or write");
				}
				x = atoi(xbuf);
				y = atoi(ybuf);
				g_object_set (png_overlay, "offset-x", x, "offset-y", y, NULL);
				g_object_set (text_overlay, "text","电视小", "font-desc","Sans, 20", "halignment","left", 
											"valignment","top", "line-alignment","center",NULL);
				flag_text = 1;channel = 0x11;break;

        	case 0x12:
		         close(x_pal2_fd);
		         close(y_pal2_fd);
		         close(x_pal1_fd);
		         close(y_pal1_fd);
				if((x_camlink_fd = open("x.txt",O_RDWR|O_CREAT))< 0){
    
    
					perror("open");
				}
				if((y_camlink_fd = open("y.txt",O_RDWR|O_CREAT))< 0){
    
    
					perror("open");
					return NULL;
				}
				memset(xbuf, 0, 4);
				memset(ybuf, 0, 4);
				if((read(x_camlink_fd, xbuf, 4) || read(y_camlink_fd, ybuf, 4)) == 0){
    
    
					perror("read or write");
				}
				x = atoi(xbuf);
				y = atoi(ybuf);
				g_object_set (png_overlay, "offset-x", x, "offset-y", y, NULL);
				g_object_set (text_overlay, "text","热像", "font-desc","Sans, 20", "halignment","left", 
											"valignment","top", "line-alignment","center",NULL);
				flag_text = 1;channel = 0x12;break;
			default:break;

		  	}

	 	}

  	}
//	close(x_pal1_fd);
//	close(y_pal1_fd);
//	close(x_pal2_fd);
//	close(y_pal2_fd);
//	close(x_camlink_fd);
//   close(y_camlink_fd);    
    return NULL;
}

这段代码的重点在while循环里。

通过查阅close系统调用说明,当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在终止时内核也会自动关闭它打开的所有文件。当我注释掉while外面的close时,按ctrl+c或者直接断电终止程序运行,发现修改的数据并没有保存到磁盘里。反之不注释则会保存。(在这一直是懵逼状态没弄清楚怎么回事,和官方说明不一致。)也就是在while(1)里open的文件,终止程序时没调用close时修改的文件并没有保存到磁盘中。而在循环外加了close释放将会实现保存。但是按理说程序并不会执行到while(1)外面的close。

留在这里当做一个备忘录。希望能尽快解决这个问题。

猜你喜欢

转载自blog.csdn.net/qq_41563600/article/details/103498181