struct flock { short l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */ off_t l_start; /* offset in bytes, relative to l_whence */ short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_len; /* length in bytes, 0 means lock to EOF */ pid_t l_pid; /* returned with F_GETLK */ };
#include <fcntl.h> int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) { struct flock lock; lock.l_type = type; lock.l_start = offset; lock.l_whence = whence; lock.l_len = len; int ret = fcntl(fd, cmd, &lock); return ret; }
若是兩個進程相互等待對方持有而且鎖定的資源時,則這兩個進程處於死鎖狀態網絡
#include <select.h> int select(int maxfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
中間三個參數 readfds, writefds, exceptfds是指向描述符集的指針,每一個描述符集存放在一個fd_set中:app
這三個參數指針任意一個能夠爲空指針,表示對相應狀態並不關心。若是三個指針都是空指針,則select提供了比sleep更精確的計時器,由於sleep只能等待整數秒,socket
而select的struct timeval能夠精確到微秒函數
int FD_ISSET(int fd, fd_set* set); void FD_CLR(int fd, fd_set* set); void FD_SET(int fd, fd_set* set); void FD_ZERO(fd_set* set);
select的第一個參數maxfds是三個描述符集中最大的fd數值加1,也能夠將此參數設置爲FD_SETSIZE,代表最大的描述符數spa
fd_set readset, writeset; FD_ZERO(&readset); FD_ZERO(&writeset); FD_SET(0, &readset); FD_SET(3, &readset); FD_SET(1, &writeset); FD_SET(2, &writeset); select(4, &readset, &writeset, NULL, NULL);
由於描述符編號從0開始,因此要在最大描述符編號值加1,第一個參數實際上就是要檢查的描述符數(從描述符0開始)指針
int readn(int fd, char* ptr, size_t n) { size_t nleft = n; int nread = 0; while (nleft > 0) { if ((nread = read(fd, ptr, nleft)) < 0) { if (nleft == n) { return -1; } else { break; } } else if (nread == 0) { break; } nleft -= nread; ptr += nread; } return n - nleft; }
int writen(int fd, char* ptr, size_t n) { size_t nleft = n; int nwrite = 0; while (nleft > 0) { if ((nwrite = write(fd, ptr, nleft)) < 0) { if (nleft == n) { return -1; } else { break; } } else if (nwrite == 0) { break; } nleft -= nwrite; ptr += nwrite; } return n - nleft; }
#include <sys/mman.h> void* mmap(void* addr, size_t len, int prot, int flag, int fd, off_t off);
#include <unistd.h> #include <string.h> #include <sys/mman.h> #include <fcntl.h> #include <sys/types.h> #include <stdio.h> int main(int argc, char* argv[]) { int fdin = 0; int fdout = 0; char* src = NULL; char* dst = NULL; struct stat statbuf; if (argc != 3) { fprintf(stderr, "usage: %s <fromfile> <tofile>\n", argv[0]); return 1; } if ((fdin = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "cannot open %s for reading\n", argv[1]); } if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC)) < 0) { fprintf(stderr, "cannot creat %s for writing\n", argv[2]); } if (fstat(fdin, &statbuf)) { fprintf(stderr, "fsat error\n"); } if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1) { fprintf(stderr, "lseek error\n"); } if (write(fdout, "", 1) != 1) { fprintf(stderr, "write error\n"); } if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == MAP_FAILED) { fprintf(stderr, "mmap error for input\n"); } if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0)) == MAP_FAILED) { fprintf(stderr, "mmap error for output\n"); } memcpy(dst, src, statbuf.st_size); munmap(src, statbuf.st_size); munmap(dst, statbuf.st_size); return 0; }