POSIX無緩衝文件I/O及可變參數小玩

這段以前寫的測試程序包含了對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);

}
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章