2008年4月20日 星期日

[C] File Locking @ Windows & FreeBSD

使用上儘管對第三者進行 locking ,或是避免使用 BufferI /O,不然容易出現資料不同步的現象,且跟 OS 的相依性會提高,對於要移值的程式就容易頭大啦!

開發與環境

Windows XP with SP3 + Dev-C++ v4.9.9.2 (gcc 3.4.2 )
FreeBSD 6.2-RELEASE-p1 (gcc 3.4.6)

程式碼:


#ifdef _WORK_FOR_WIN32_


#include <windows.h>
#include <io.h>


#endif


void File_LockByPtr( FILE * fd )
{
#ifndef _WORK_FOR_WIN32_
        struct flock fl;
        fl.l_type = F_WRLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();
        if( fcntl( fileno( fd )  , F_SETLKW , &fl ) < 0 )
        {
                perror("Lock File Pointer Error @ LockFilePtr");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle(_fileno( fd ));
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));
        if( LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ovl) == 0 )
        {
                perror("Lock File Pointer Error @ LockFilePtr");
                exit(1);
        }
#endif


}
void File_UnlockByPtr( FILE * fd )
{
#ifndef _WORK_FOR_WIN32_
        struct flock fl;


#ifndef SYS_OPT_LOCKING_FILE_PONITER_WITHOUT_FFLUSH
        fflush(fd);
#endif


        fl.l_type = F_UNLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();


        if( fcntl( fileno( fd )  , F_SETLK , &fl ) < 0 )
        {
                perror("Unlock File Pointer Error @ UnlockFilePtr");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle(_fileno( fd ));
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));


#ifndef SYS_OPT_LOCKING_FILE_PONITER_WITHOUT_FFLUSH
        fflush( fd );
#endif


        if( UnlockFileEx(hFile, 0, 1, 0, &ovl) == 0 )
        {
                perror("Unlock File Pointer Error @ UnlockFileByPtr");
                exit(1);
        }
#endif
}
void File_LockByFD( int fd )
{
#ifndef WIN32
        struct flock fl;
        fl.l_type = F_WRLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();
        if( fcntl( fd , F_SETLKW , &fl ) < 0 )
        {
                fprintf( stderr , "Lock File Pointer Error @ LockFilePtr\n");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle( fd );
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));
        if( ( lock_status = LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ovl) ) == 0 )
        {
                fprintf( stderr , "Lock File Pointer Error @ LockFileFD\n");
                exit(1);
        }
#endif

}
void File_UnlockByFD( int fd )
{
#ifndef WIN32
        struct flock fl;

        fl.l_type = F_UNLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();

        if( fcntl( fd , F_SETLK , &fl ) < 0 )
        {
                fprintf( stderr , "Unlock File Pointer Error @ UnlockFilePtr\n");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle( fd );
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));

        if( UnlockFileEx(hFile, 0, 1, 0, &ovl) == 0 )
        {
                fprintf( stderr , "Unlock File Pointer Error @ UnlockFileByFD\n");
                exit(1);
        }
#endif
}


用法:


if( ( opt->dblock = fopen( lock_file , "w" ) )  == NULL )
{
         fprintf( stderr , "Cannot Open Lock File @ DB_Lock\n" );
         exit(1);
}
File_LockByPtr( opt->dblock );

...

File_UnlockByPtr( opt->dblock );
fclose(opt->dblock);



#ifndef WIN32
        struct flock fl;
        if( ( db_lock_fd = open( db_lock_file ,  O_RDWR | O_CREAT ) )  == -1 )
#else
        HANDLE hFile;
        OVERLAPPED ovl;
        if( ( db_lock_fd = _open( db_lock_file ,  _O_RDWR | _O_CREAT , _S_IREAD| _S_IWRITE ) )  == -1 )
#endif
        {
                switch( errno )
                {
                case EACCES:
                        printf("Tried to open read-only file for writing, file's sharing mode does not allow specified operations, or given path is directory.\n");
                        break;
                case EEXIST:
                        printf("_O_CREAT and _O_EXCL flags specified, but filename already exists.\n");
                        break;
                case EINVAL:
                        printf("Invalid oflag or pmode argument.\n");
                        break;
                case EMFILE:
                        printf("No more file descriptors available (too many open files).\n");
                        break;
                case ENOENT:
                        printf("File or path not found.\n");
                        break;
                }
                fprintf( stderr , "Cannot Open Lock File @ db_lock ,%d, %s\n" , errno , db_lock_file );
                exit(1);
        }
        File_LockByFD( db_lock_fd );

        ...

        File_UnlockByFD( db_lock_fd );


2008年4月19日 星期六

工作與興趣的分隔線

今早悟出一個心得:「工作的部分,用工作的態度面對;興趣的部分,用興趣的態度面對」。

這樣的分界,是因為些前都是用興趣的方式來面對工作,所以很容易因為工作上的興趣缺缺,導致事情進行起來,苦悶許多!但這樣的分界不是對兩邊的負責態度不一,而是處理上時,心態需要微調。

昨天,原本想改寫學長寫的程式架構,覺得彈性不夠大,但說穿了只是想要用自己的方式去詮釋!今早花了點時間將其架構走了一遍,工作還是要用工作的態度面對,儘管整體架構不是自己熟悉的 framework ,就把它當做訓練跟別人合作吧!學會欣賞別人的架構,也是一門重要的學問!人,總要站在巨人的肩膀上!

至於興趣?最近花了很多時間在工作上,我想,我該為我的興趣負點責任,該花點時間想點好玩的事來碰碰。

2008年4月18日 星期五

傳承

四月天,嗅到一點離別的滋味。

相信在沒多久,自己就要負荷起實驗室中的老大哥。心情有點兒不適,或者更說是不捨。小大一常常跑來詢問東探望西的,未來若沒了現在的老大哥,總覺得自己的能力似乎還不夠稱職,然而,簡單的談天,其實也挺自在舒服的。

最近上頭的開始在進行一連串的移交,傳承,很巧地我碰上了這個交界點,或許又將學習到很多的東西,至少得提足精神好好面對,珍惜一切的機會,相信,躍進會從此開始的。

簡單的信念:「我想要成功」,儘管現在苦哈哈的,但相信與身體力行,一定會有好結果的!

2008年4月17日 星期四

空‧心

有股空虛的感觸,抹一點心虛的成份。 悶悶的,想玩卻不知要玩什麼,想睡,最近卻常常睡不好?

剛終於看了一下學長設計的介面,發現差別真大!自己的能力還差那麼多。除此之外,接近六月,又是個離別潮,耳邊常傳來”誰誰誰將要離開,未來不知該請教誰了!”,說真的,自己倒還不能獨當一面,能力這種東西,沒想到日積月累差異真大,而碩班的生活,說穿了只是幫人做事,真正想要專研自己的方向的機會,少之又少,我甚至會懷疑,科技替代役的履歷表上,將有幾項是碩班可拿出成果?時間過得真的很快,我也漸漸落於嘴砲的旋渦中。

最近太善變,心情好的時候很好,糟的時候很悶,開始能體會某人在大學時跟我說過的話,善變,有時不需要理由,也終將釐不清!彷彿剛剛證明出來的式子,一下子就被指出矛盾的地方,怎麼證都證不好,那答案,是否真的重要?我開始欣賞,那位竟然可以這麼自在地順起情緒行事,而我,放不開。

成天寫程式的生活太過單調,征服的快感也只是一瞬,我該找點樂子熱熱場子。

2008年4月15日 星期二

考試時刻

又到了期中考,這學期很忙,忙著Meeting、忙著Thinking、忙著Coding。

電腦前播放著兒時熟悉的哆啦ㄟ夢,沒想到那幼稚園的氣氛讓我倍感輕盈。洗澡時想起上學期很白癡的行為舉止,儘管二十五歲偶爾也會累犯。總是到了考試時,才會靜下來想想東西,摸摸古老的回憶。逛逛許久沒到訪的個人板,一篇篇六七年前的文章,一字字想也不敢想的青澀詞句,一股腦兒跌進眼簾,原來過去是那般,那般地叫人不敢回想,隨著時間往往已不是舊式的自己,拾不起的點滴再也沒有起點。

喜歡哆啦ㄟ夢的日語配音,也只有這份熟悉才叫醒兒時的自我。日子果然倏地變動,或許回憶是存在對現實的不安全感吧!