#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<fcntl.h> int lock_set(int fd,int type) { struct flock 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 alread set by %d\n",lock.l_pid); } else if(lock.l_type == F_WRLCK) { printf("Write lock alread set by %d\n",lock.l_pid); } } 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()); } break; case F_WRLCK: { printf("Write lock set by %d\n",getpid()); } break; case F_UNLCK: { printf("Release lock by %d\n",getpid()); } break; } return 0; } int custum() { int fs,fd; int count; char c; if((fs = open("produce.txt",O_RDWR)) < 0) { printf("open error\n"); return -1; } // if((fd = open("temp.txt",O_RDWR)) < 0) // { // printf("open error2\n"); // return -1; // } while(1) { lock_set(fs,F_WRLCK); lseek(fs,0,SEEK_SET); fd=open("temp.txt",O_RDWR|O_CREAT|O_TRUNC,0777); count=read(fs,&c,1); if(count <= 0) { printf("no product!\n"); lock_set(fs,F_UNLCK); sleep(1); continue; } printf("get a character: %c \n",c); // lseek(fs,0,SEEK_CUR); // lseek(fd,0,SEEK_SET); // count = 0; while(((count = read(fs,&c,1)) == 1) /*&& c!= '\n'*/) { printf("read fs: %c\n", c); write(fd,&c,count); } close(fs); fs = open("produce.txt",O_RDWR|O_TRUNC); //liuzx_bj@hqyj.com lseek(fs,0,SEEK_SET); lseek(fd,0,SEEK_SET); while(((count = read(fd,&c,1)) == 1) /*&& c!='\n'*/) { // printf("read fd: %c\n", c); write(fs,&c,count); } unlink("temp.txt"); close(fd); lock_set(fs,F_UNLCK); sleep(2); } } int main(int argc, const char *argv[]) { custum(); return 0; }
运行程序时,生产文件里有ABC 3个产品,运行时发现最后一个C产品一直会重复取出,经检查发现:我将produce.txt中的剩余产品复制到temp.txt中,之后再复制回来,我只是将文件读写位置调到了起始,但是以读写方式打开文件produce.txt,其中的产品仍为ABC,将temp.txt中的BC复制回去时,只是覆盖AB为BC最后的C仍存在,所以会一直有C。解决这个问题是:关闭produce.txt的文件符,重新以读写,清除原文件内容的方式打开,就会成功。只是还有一个问题read函数读到最后貌似自动会读一个'\n'。不加语句c!='\n'的话,会将\n一直复制下去。
生产者函数如下:
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<fcntl.h> int lock_set(int fd,int type) { struct flock 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 alread set by %d\n",lock.l_pid); } else if(lock.l_type == F_WRLCK) { printf("Write lock alread set by %d\n",lock.l_pid); } } 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()); } break; case F_WRLCK: { printf("Write lock set by %d\n",getpid()); } break; case F_UNLCK: { printf("Release lock by %d\n",getpid()); } break; } return 0; } int produce() { int fd; char a='A'; if((fd = open("produce.txt",O_WRONLY|O_APPEND)) < 0) { printf("open failed\n"); return -1; } while(1) { lock_set(fd,F_WRLCK); write(fd,&a,1); printf("hava produce one character %c \n",a); a++; lock_set(fd,F_UNLCK); sleep(3); } close(fd); } int main(int argc, const char *argv[]) { produce(); return 0; }