这段以前写的测试程序包含了对POSIX无缓冲文件I/O、文件加解锁、进程分叉、可变参数的综合运用。没什么技术含量,纯粹记述一下,不想有一天弄丢了。
C真是又小巧又灵活,在语言的犄角旮旯还是存在一些之前完全想不到会有的特性,呵呵~不过,现在可能会从事的这个工作是不是只能用C不能用C++呢?难道真的得告别自己的最爱?
//posix
#include <unistd.h>
#include <sys/types.h> //for pid_t
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
//randoming
#include <stdlib.h> //for random
#include <time.h> //for srand with time
//variable parameter list
#include <stdarg.h>
//common
#include <stdio.h>
#include <string.h>
void my_read();
void my_write();
void lock_set(int fd, int type);
void my_lock_test(int n_tests, ...);
int main()
{
my_read();
my_write();
srand( (unsigned int) time(0));
fork();
my_lock_test(4, F_WRLCK, F_UNLCK, F_RDLCK, F_UNLCK);
exit(0);
}
void my_read()
{
int fd;
if((fd = open("/tmp/hello.c", O_CREAT|O_TRUNC|O_WRONLY, 0600)) < 0)
{
perror("open:");
exit(1);
}
else
printf("Open file: hello.c %d/n", fd);
if(close(fd) < 0)
{
perror("close:");
exit(1);
}
else
printf("Close hello.c/n");
}
void my_write()
{
int fd, size, len;
char* buf = "Hello! I'm writing to this file";
char buf_r[10];
len = strlen(buf);
if((fd = open("/tmp/hello.c", O_CREAT|O_TRUNC|O_RDWR, 0666)) < 0)
{
perror("open:");
exit(1);
}
else
printf("Open file: hello.c %d/n", fd);
if((size = write(fd, buf, len)) < 0)
{
perror("write:");
exit(1);
}
else
printf("Writes: %s/n", buf);
lseek(fd, 0, SEEK_SET);
if((size = read(fd, buf_r, 10)) < 0)
{
perror("read:");
exit(1);
}
else
printf("read first 10 characters from file: %s/n", buf_r);
if(close(fd) < 0)
{
perror("close:");
exit(1);
}
else
printf("Close hello.c/n");
}
void lock_set(int fd, int type)
{
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
while(1)
{
lock.l_type = type;
if((fcntl(fd, F_SETLK, &lock)) == 0)
{
if(lock.l_type == F_RDLCK)
printf("read lock set by %d/n", getpid());
else if(lock.l_type == F_WRLCK)
printf("write lock set by %d/n", getpid());
else if(lock.l_type == F_UNLCK)
printf("release lock by %d/n", getpid());
return;
}
fcntl(fd, F_GETLK, &lock);
if(lock.l_type != F_UNLCK)
{
if(lock.l_type == F_RDLCK)
printf("%d: read lock already set by %d/n", getpid(), lock.l_pid);
else if(lock.l_type == F_WRLCK)
printf("%d: write lock already set by %d/n", getpid(), lock.l_pid);
sleep(random() % 3);
}
}
}
void my_lock_test(int n_tests, ...)
{
va_list test_cases;
int cur;
int fd;
fd = open("/tmp/hello.c", O_RDWR|O_CREAT, 0666);
if(fd < 0)
{
perror("lock test open:");
exit(1);
}
va_start(test_cases, n_tests);
for(cur = 0; cur < n_tests; ++cur)
{
lock_set(fd, va_arg(test_cases, int));
sleep(random() % 5);
}
va_end(test_cases);
}