這段以前寫的測試程序包含了對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("Openfile:hello.c%d\n",fd);
if (close(fd)<0)
{
perror("close:");
exit(1);
}
else
printf("Closehello.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("Openfile: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("Closehello.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:writelockalreadysetby%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);
}