小米筆記本 Pro X 現身小米有品,將於 6 月 1 日開售
阿新 • • 發佈:2021-05-18
專案 | 內容 |
---|---|
這個作業屬於哪個課程 | <班級課程的主頁連結> |
這個作業的要求在哪裡 | <作業要求連結接地址> |
學號-姓名 | 18043213-丁宇航 |
作業學習目標 |
瞭解程序間通訊的常用方式; 掌握管道、訊息佇列、訊號量、共享記憶體實現程序間通訊的方法。 |
1. 舉例說明使用匿名管道進行程序通訊。
當程序使用 pipe 函式,就可以開啟位於核心中的這個特殊“檔案”。同時 pipe 函式會返回兩個描述符,一個用於讀,一個 用於寫。如果你使用 fstat 函式來測試該描述符,可以發現此檔案型別為FIFO 。而無名管道的無名,指的就是這個虛幻 的“檔案”,它沒有名字。 man 2 pipe 父程序 fork 出一個子程序,通過無名管道向子程序傳送字元,子程序收到資料後將字串中的小寫字元轉換成大寫並輸出。2. 舉例說明使用mkfifo
3. 編寫兩個程式使用第2題中建立的管道進行通訊。
分別開啟兩個終端,分別執行 pipesend 和 piperecv : 現在兩個終端都處於阻塞狀態,我們在執行 pipe_send 的終端輸入資料,然後我們就可以在執行 pipe_recv 的終端看到相應的輸出:4. 編寫兩個程式分別通過指定的鍵值建立IPC
IPC
核心物件。
程式 ipccreate 用於在指定的鍵值上建立 ipc 核心物件。./ipccreate 0 0x8888 表示在鍵值 0x8888 上建立共享記憶體。
程式 ipcget 用於在指定的鍵值上獲取 ipc 核心物件的 id 號。./ipcget 0 0x8888 表示獲取鍵值 0x8888 上的共享記憶體 id 號。
5. 編寫一個程式可以用來建立、刪除核心物件,也可以掛接、解除安裝共享記憶體,還可以列印、設定核心物件資訊。
./shmctl -c : 建立核心物件。 ./shmctl -d : 刪除核心物件。 ./shmctl -v : 顯示核心物件資訊。 ./shmctl -s : 設定核心物件(將許可權設定為 0600 )。 ./shmctl -a : 掛接和解除安裝共享記憶體(掛接 5 秒後,再執行 shmdt ,然後退出)。shmctl.c #include先在另一個終端執行 ./shmctl -a ,然後在當前終端執行 ./shmctl -v<unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h> #define ASSERT(res) if((res)<0){perror(__FUNCTION__);exit(-1);} // 列印 ipc_perm void printPerm(struct ipc_perm *perm) { printf("euid of owner = %d\n", perm->uid); printf("egid of owner = %d\n", perm->gid); printf("euid of creator = %d\n", perm->cuid); printf("egid of creator = %d\n", perm->cgid); printf("mode = 0%o\n", perm->mode); } // 列印 ipc 核心物件資訊 void printShmid(struct shmid_ds *shmid) { printPerm(&shmid->shm_perm); printf("segment size = %ld\n", shmid->shm_segsz); printf("last attach time = %s", ctime(&shmid->shm_atime)); printf("last detach time = %s", ctime(&shmid->shm_dtime)); printf("last change time = %s", ctime(&shmid->shm_ctime)); printf("pid of creator = %d\n", shmid->shm_cpid); printf("pid of last shmat/shmdt = %d\n", shmid->shm_lpid); printf("No. of current attaches = %ld\n", shmid->shm_nattch); } // 建立 ipc 核心物件 void create() { int id = shmget(0x8888, 123, IPC_CREAT | IPC_EXCL | 0664); printf("create %d\n", id); ASSERT(id); } // IPC_STAT 命令使用,用來獲取 ipc 核心物件資訊 void show() { int id = shmget(0x8888, 0, 0); ASSERT(id); struct shmid_ds shmid; ASSERT(shmctl(id, IPC_STAT, &shmid)); printShmid(&shmid); } // IPC_SET 命令使用,用來設定 ipc 核心物件資訊 void set() { int id = shmget(0x8888, 123, IPC_CREAT | 0664); ASSERT(id); struct shmid_ds shmid; ASSERT(shmctl(id, IPC_STAT, &shmid)); shmid.shm_perm.mode = 0600; ASSERT(shmctl(id, IPC_SET, &shmid)); printf("set %d\n", id); } // IPC_RMID 命令使用,用來刪除 ipc 核心物件 void rm() { int id = shmget(0x8888, 123, IPC_CREAT | 0664); ASSERT(id); ASSERT(shmctl(id, IPC_RMID, NULL)); printf("remove %d\n", id); } // 掛接和解除安裝 void at_dt() { int id = shmget(0x8888, 123, IPC_CREAT | 0664); ASSERT(id); char *buf = shmat(id, NULL, 0); if (buf == (char*)-1) ASSERT(-1); printf("shmat %p\n", buf); sleep(5); // 等待 5 秒後,執行 shmdt ASSERT(shmdt(buf)); printf("shmdt %p\n", buf); } int main(int argc, char *argv[]) { if (argc < 2) { printf("usage: %s <option -c -v -s -d -a>\n", argv[0]); return -1; } printf("I'm %d\n", getpid()); if (!strcmp(argv[1], "-c")) { create(); } else if (!strcmp(argv[1], "-v")) { show(); } else if (!strcmp(argv[1], "-s")) { set(); } else if (!strcmp(argv[1], "-d")) { rm(); } else if (!strcmp(argv[1], "-a")) { at_dt(); } return 0; }
6. 編寫兩程式分別用於向訊息佇列傳送資料和接收資料。
msg_send
程式定義了一個結構體Msg
,訊息正文部分是結構體Person
。該程式向訊息佇列傳送了10
條訊息。
7. 編寫程式舉例說明訊號量如何操作。
設定和獲取訊號量值的函式 semctl : man 2 semctl 請求和釋放訊號量 semop man 2 semop 訊號量操作8. 編寫程式使用訊號量實現父子程序之間的同步,防止父子程序搶奪CPU
。