版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、實驗四:Linux進程及文件操作程序設(shè)計第一部分 Linux下文件控制程序設(shè)計一、實驗目的 1. 熟悉Linux下文件控制程序設(shè)計方法。 2. 掌握利用文件鎖實現(xiàn)文件互斥訪問程序設(shè)計方法。 二、實驗設(shè)備裝有RedHat EnterpriseLinux操作系統(tǒng)的PC機三、實驗內(nèi)容1、預備知識 當多個用戶共同使用、操作一個文件時,Linux 通常采用的方法是給文件上鎖,來避免共享的資源產(chǎn)生競爭的狀態(tài)。文件鎖包括建議性鎖和強制性鎖。建議性鎖要求每個上鎖文件的進程都要檢查是否有鎖存在,并且尊重已有的鎖。在一般情況下,內(nèi)核和系統(tǒng)都不使用建議性鎖。強制性鎖是由內(nèi)核執(zhí)行的鎖,當一個文件被上鎖進行寫入操作的時
2、候,內(nèi)核將阻止其他任何文件對其進行讀寫操作。采用強制性鎖對性能的影響很大,每次讀寫操作都必須檢查是否有鎖存在。 在Linux 中,實現(xiàn)文件上鎖的函數(shù)有flock和fcntl,其中flock用于對文件施加建議性鎖,而fcntl不僅可以施加建議性鎖,還可以施加強制鎖。同時,fcntl還能對文件的某一記錄進行上鎖,也就是記錄鎖。 記錄鎖又可分為讀取鎖和寫入鎖,其中讀取鎖又稱為共享鎖,它能夠使多個進程都能在文件的同一部分建立讀取鎖。而寫入鎖又稱為排斥鎖,在任何時刻只能有一個進程在文件的某個部分上建立寫入鎖。當然,在文件的同一部分不能同時建立讀取鎖和寫入鎖。 2、fcntl()函數(shù)格式 用于建立記錄鎖的
3、fcntl函數(shù)格式如表7.1所示。 表7.1 fcntl函數(shù)語法要點 所需頭文件 #include #include #include 函數(shù)原型 int fcnt1(int fd,int cmd,struct flock *lock) 函數(shù)傳入?yún)?shù) fd 文件描述符 cmd(命令)F_DUPFD:復制文件描述符 F_GETFL:得到open設(shè)置的標志 F_SETFL:改變open設(shè)置的標志 F_SETLK:設(shè)置lock描述的文件鎖 F_SETLKW:這是F_SETLK的阻塞版本 F_GETLK:獲取上鎖狀態(tài)。 lock 設(shè)置鎖參數(shù) 函數(shù)返回值 成功:0 出錯:1 這里,lock的結(jié)構(gòu)如下所示:
4、 struct flock short l_type; off_t l_start; short l_whence; off_t l_len; pid_t l_pid; lock結(jié)構(gòu)中每個變量的取值含義如表7.2所示。表7.2 lock結(jié)構(gòu)變量取值 l_type F_RDLCK:讀取鎖(共享鎖) F_WRLCK:寫入鎖(排斥鎖) F_UNLCK:解鎖 l_stat 相對位移量(字節(jié)) l_whence:相對位移量的起點 SEEK_SET:當前位置為文件的開頭,新位置為偏移量的大小。 SEEK_CUR:當前位置為文件指針的位置,新位置為當前位置加上偏移量。 SEEK_END:當前位置為文件的結(jié)尾
5、,新位置為文件的大小加上偏移量的大小。 l_len 加鎖區(qū)域的長度。 說明 為加鎖整個文件,通常的方法是將l_start =0,l_whence=SEEK_SET,l_len=0。 3、實驗內(nèi)容 編程實現(xiàn)使用fcntl 函數(shù)為文件上鎖的程序。首先創(chuàng)建了一個hello文件,之后對其上寫入鎖,最后釋放寫入鎖。 編程步驟如下: 1)首先對flock結(jié)構(gòu)體的對應位賦予相應的值。 2)接著調(diào)用fcntl函數(shù)判斷文件是否可以上鎖,如果可以,則對其上寫入鎖(F_SETLKW);如果已有鎖存在,則打印鎖類型及上鎖進程號,并為其上阻塞性寫文件鎖(F_SETLKW)。 四、實驗步驟1、新建一個子目錄。 cd /h
6、ome mkdir exp5 cd exp5 2、編寫實現(xiàn)上述功能的程序代碼 編輯上鎖子函數(shù):vi lock_set.c 啟動vi,然后,按i進入插入狀態(tài),并輸入源程序。最后,按ESC返回到底行模式,并按:wq存盤退出。 編輯寫鎖測試主程序:vi write_lock.c啟動vi,然后,按i進入插入狀態(tài),并輸入源程序。最后,按ESC返回到底行模式,并按:wq存盤退出。 3、編譯、調(diào)試上述程序。 gcc write_lock.c o write_lock 4、在PC機端開啟兩個終端,并且在兩個終端上同時運行該程序,以達到多個進程操作一個文件的效果。 新建第一個終端:桌面點右鍵選擇“新建一個終端”
7、 運行write_lock:./ write_lock (第一個終端對hello文件加寫鎖) 新建第二個終端:桌面點右鍵選擇“新建一個終端” 運行write_lock:./ write_lock (第二個終端對hello文件加寫鎖,由于第一個寫鎖還未退出,所以該寫鎖被阻塞) 在第一個終端按任意鍵,進行文件解鎖。 觀察第二個終端,加鎖成功。 5、觀察實驗結(jié)果。 首先在終端一上運行./write_lock,然后新建另一個終端并運行./write_lock,由于第一個終端上已經(jīng)給文件hello上鎖了,所以第二個終端程序不能對文件hello上鎖而被阻塞。 在第一個終端上,按任意鍵,使其釋放寫文件鎖。此
8、時,觀察終端二可以發(fā)現(xiàn),終端二上的加鎖程序完成了加鎖任務(wù)。 五、實驗程序清單1、實現(xiàn)文件加鎖的子程序/* lock_set.c */ int lock_set(int fd, int type) struct flock old_lock, lock; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_type = type; lock.l_pid = -1; /* 判斷文件是否可以上鎖 */ fcntl(fd, F_GETLK, &lock); if (lock.l_type != F_UNLCK) /* 判
9、斷文件不能上鎖的原因 */ if (lock.l_type = F_RDLCK) /* 該文件已有讀取鎖 */ printf(Read lock already set by %dn, lock.l_pid); else if (lock.l_type = F_WRLCK) /* 該文件已有寫入鎖 */ printf(Write lock already set by %dn, lock.l_pid); /* l_type 可能已被F_GETLK修改過 */ lock.l_type = type; /* 根據(jù)不同的type值進行阻塞式上鎖或解鎖 */ if (fcntl(fd, F_SETLK
10、W, &lock) 0) printf(Lock failed:type = %dn, lock.l_type); return 1; switch(lock.l_type) case F_RDLCK: printf(Read lock set by %dn, getpid(); break; case F_WRLCK: printf(Write lock set by %dn, getpid(); break; case F_UNLCK: printf(Release lock by %dn, getpid(); return 1; break; default: break; /* end
11、 of switch */ return 0; 2、測試用主程序/* write_lock.c */ #include #include #include #include #include #include #include #include lock_set.c int main(void) int fd; /* 首先打開文件 */ fd = open(hello, O_RDWR | O_CREAT, 0644); if(fd 0) printf(Open file errorn); exit(1); /* 給文件上寫入鎖 */ lock_set(fd, F_WRLCK); getchar
12、(); /* 給文件解鎖 */ lock_set(fd, F_UNLCK); getchar(); close(fd); return 0; 第二部分: Linux下的多線程程序設(shè)計一、實驗目的 1、 通過編寫經(jīng)典的“生產(chǎn)者消費者”問題,進一步熟悉Linux 中多線程編程 2、 掌握用信號量處理線程間的同步互斥的方法。 二、實驗設(shè)備裝有RedHat EnterpriseLinux操作系統(tǒng)的PC機三、實驗內(nèi)容“生產(chǎn)者消費者”問題描述如下: 有一個有限緩沖區(qū)和兩個線程:生產(chǎn)者和消費者。他們分別把產(chǎn)品放入緩沖區(qū)和從緩沖區(qū)中拿走產(chǎn)品。生產(chǎn)者在緩沖區(qū)滿時必須等待,消費者在緩沖區(qū)空時必須等待。同時,要求生
13、產(chǎn)者和消費者不能同時訪問緩沖區(qū)。它們之間的關(guān)系如圖1所示: 圖1 生產(chǎn)者消費者問題描述這里要求用有名管道來模擬有限緩沖區(qū),用信號量來解決生產(chǎn)者消費者問題中的同步和互斥問題。1、信號量的考慮可以使用3個信號量,其中兩個信號量avail和full分別用于解決生產(chǎn)者和消費者線程之間的同步問題,mutex是用于這兩個線程之間的互斥問題。其中avail初始化為N(有界緩沖區(qū)的空單元數(shù)),mutex 初始化為1,full初始化為0。2、流程圖“生產(chǎn)者消費者”問題的流程流程圖如圖2所示。3、編寫代碼實驗代碼中采用的有界緩沖區(qū)擁有3個單元,每個單元為5個字節(jié)。為了盡量體現(xiàn)每個信號量的意義,在程序中生產(chǎn)過程和消
14、費過程隨機(采取0-5s的隨機時間間隔)進行的,而且生產(chǎn)者的速度比消費者的速度平均快兩倍左右。生產(chǎn)者一次生產(chǎn)一個產(chǎn)品(向緩沖區(qū)中放入“hello”字符串),消費者一次消費一個產(chǎn)品。四、實驗步驟1、新建目錄存放所設(shè)計的程序。cd /homemkdir exp8cd exp82、編寫“生產(chǎn)者消費者”問題的程序。輸入命令 vi producer-customer.c 啟動vi,然后,按i進入插入狀態(tài),并輸入源程序。最后,按ESC返回到底行模式,并按:wq存盤退出。3、編譯、調(diào)試上述程序。gcc producer-customer.c o producer-customer lpthread4、新建一
15、個終端:桌面點右鍵選擇“新建一個終端”運行 ./producer-customer5、觀察實驗結(jié)果。圖2. “生產(chǎn)者消費者”問題的流程流程圖五、參考程序清單/*producer-customer.c*/ #include #include #include #include #include #include #include #include #include #include #define MYFIFO myfifo /* 緩沖區(qū)有名管道的名字 */#define BUFFER_SIZE 3 /* 緩沖區(qū)的單元數(shù) */#define UNIT_SIZE 5 /* 每個單元的大小 */#d
16、efine RUN_TIME 30 /* 運行時間 */#define DELAY_TIME_LEVELS 5.0 /* 周期的最大值 */int fd;time_t end_time;sem_t mutex, full, avail; /* 三個信號量 */*生產(chǎn)者線程*/void *producer(void *arg)int real_write;int delay_time = 0;while(time(NULL) end_time)delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) / 2.0) + 1;sleep(del
17、ay_time);/*P操作信號量avail和mutex*/sem_wait(&avail);sem_wait(&mutex);printf(nProducer: delay = %dn, delay_time);/*生產(chǎn)者寫入數(shù)據(jù)*/if (real_write = write(fd, hello, UNIT_SIZE) = -1)if(errno = EAGAIN)printf(The FIFO has not been read yet.Please try latern);elseprintf(Write %d to the FIFOn, real_write); /*V操作信號量fu
18、ll和mutex*/sem_post(&full);sem_post(&mutex);pthread_exit(NULL);/* 消費者線程*/void *customer(void *arg)unsigned char read_bufferUNIT_SIZE;int real_read;int delay_time;while(time(NULL) end_time)delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) + 1;sleep(delay_time);/*P操作信號量full和mutex*/sem_wait(&full
19、);sem_wait(&mutex);memset(read_buffer, 0, UNIT_SIZE);printf(nCustomer: delay = %dn, delay_time);if (real_read = read(fd, read_buffer, UNIT_SIZE) = -1)if (errno = EAGAIN)printf(No data yetn);printf(Read %s from FIFOn, read_buffer);/*V操作信號量avail和mutex*/sem_post(&avail);sem_post(&mutex);pthread_exit(NU
20、LL);int main()pthread_t thrd_prd_id,thrd_cst_id;pthread_t mon_th_id; int ret;srand(time(NULL);end_time = time(NULL) + RUN_TIME;/*創(chuàng)建有名管道*/if(mkfifo(MYFIFO, 0777)0)&(errno!=EEXIST)printf(Cannot create fifon);return errno;/*打開管道*/fd = open(MYFIFO, O_RDWR);if (fd = -1)printf(Open fifo errorn);return fd;
21、/*初始化互斥信號量為1*/ret = sem_init(&mutex, 0, 1);/*初始化avail信號量為N*/ret += sem_init(&avail, 0, BUFFER_SIZE);/*初始化full信號量為0*/ret += sem_init(&full, 0, 0);if (ret != 0)printf(Any semaphore initialization failedn);return ret;/*創(chuàng)建兩個線程*/ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);if (ret != 0)printf(Create producer thread errorn);return ret;ret = pthread_create(&thrd_cst_id, NULL, customer, NULL);if(ret != 0)printf(Create customer thread err
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 氟碳漆如何施工方案(3篇)
- 汾西會議活動策劃方案(3篇)
- 消火栓更改施工方案(3篇)
- 溜井擴大施工方案(3篇)
- 煤棚擋墻施工方案(3篇)
- 碎修施工方案(3篇)
- 簡單水閘施工方案(3篇)
- 茶桌排水施工方案(3篇)
- 襄陽涂料施工方案(3篇)
- 躉船船頭施工方案(3篇)
- 2026中國電信四川公用信息產(chǎn)業(yè)有限責任公司社會成熟人才招聘備考題庫及參考答案詳解1套
- 2025年廣東省生態(tài)環(huán)境廳下屬事業(yè)單位考試真題附答案
- 2026年安徽省公務(wù)員考試招錄7195名備考題庫完整參考答案詳解
- 2023年高鐵信號車間副主任述職報告
- GB/T 879.4-2000彈性圓柱銷卷制標準型
- GB/T 1957-2006光滑極限量規(guī)技術(shù)條件
- GB 28480-2012飾品有害元素限量的規(guī)定
- 劉一秒演說智慧經(jīng)典(內(nèi)部筆記)
- 管道TOFD檢測記錄及續(xù)表
- 馬克思主義哲學精講課件
- 期末考試總安排
評論
0/150
提交評論