From 42fc313ac152fcb70f67c2f934142bac6951b3f3 Mon Sep 17 00:00:00 2001 From: "Xingyu.Wang" Date: Tue, 14 May 2019 08:56:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @lujun9972 这里两篇 IPC 的代码出现错误,是因为原文代码里面有链接解析错误导致。 @FSSlc 请注意你正在翻译的第三篇可能也有此情形。 --- ...at Improve Battery Life On Linux Laptop.md | 4 +- ... communication in Linux- Shared storage.md | 95 +++++++++---------- ...n Linux- Using pipes and message queues.md | 81 ++++++++-------- 3 files changed, 88 insertions(+), 92 deletions(-) diff --git a/published/20181212 TLP - An Advanced Power Management Tool That Improve Battery Life On Linux Laptop.md b/published/20181212 TLP - An Advanced Power Management Tool That Improve Battery Life On Linux Laptop.md index d21a4f2a44..2b38da68d0 100644 --- a/published/20181212 TLP - An Advanced Power Management Tool That Improve Battery Life On Linux Laptop.md +++ b/published/20181212 TLP - An Advanced Power Management Tool That Improve Battery Life On Linux Laptop.md @@ -108,7 +108,9 @@ $ sudo apt-get install smartmontools 当基于 Ubuntu 的系统的官方软件包过时时,请使用以下 PPA 存储库,该存储库提供最新版本。运行以下命令以使用 PPA 安装 TLP。 ``` -$ sudo apt-get install tlp tlp-rdw +$ sudo add-apt-repository ppa:linrunner/tlp +$ sudo apt-get update +$ sudo apt-get install tlp ``` 对于基于 Arch Linux 的系统,使用 [Pacman 命令][9] 安装 TLP。 diff --git a/published/20190415 Inter-process communication in Linux- Shared storage.md b/published/20190415 Inter-process communication in Linux- Shared storage.md index dba63f8782..de56a36982 100644 --- a/published/20190415 Inter-process communication in Linux- Shared storage.md +++ b/published/20190415 Inter-process communication in Linux- Shared storage.md @@ -62,47 +62,42 @@ producer-------->| disk file |<-------consumer #include #include #include +#include #define FileName "data.dat" +#define DataString "Now is the winter of our discontent\nMade glorious summer by this sun of York\n" void report_and_exit(const char* msg) { - [perror][4](msg); - [exit][5](-1); /* EXIT_FAILURE */ + perror(msg); + exit(-1); /* EXIT_FAILURE */ } int main() { struct flock lock; - lock.l_type = F_WRLCK; /* read/write (exclusive) lock */ + lock.l_type = F_WRLCK; /* read/write (exclusive versus shared) lock */ lock.l_whence = SEEK_SET; /* base for seek offsets */ lock.l_start = 0; /* 1st byte in file */ lock.l_len = 0; /* 0 here means 'until EOF' */ lock.l_pid = getpid(); /* process id */ int fd; /* file descriptor to identify a file within a process */ - if ((fd = open(FileName, O_RDONLY)) < 0) /* -1 signals an error */ - report_and_exit("open to read failed..."); + if ((fd = open(FileName, O_RDWR | O_CREAT, 0666)) < 0) /* -1 signals an error */ + report_and_exit("open failed..."); - /* If the file is write-locked, we can't continue. */ - fcntl(fd, F_GETLK, &lock); /* sets lock.l_type to F_UNLCK if no write lock */ - if (lock.l_type != F_UNLCK) - report_and_exit("file is still write locked..."); + if (fcntl(fd, F_SETLK, &lock) < 0) /** F_SETLK doesn't block, F_SETLKW does **/ + report_and_exit("fcntl failed to get lock..."); + else { + write(fd, DataString, strlen(DataString)); /* populate data file */ + fprintf(stderr, "Process %d has written to data file...\n", lock.l_pid); + } - lock.l_type = F_RDLCK; /* prevents any writing during the reading */ - if (fcntl(fd, F_SETLK, &lock) < 0) - report_and_exit("can't get a read-only lock..."); - - /* Read the bytes (they happen to be ASCII codes) one at a time. */ - int c; /* buffer for read bytes */ - while (read(fd, &c, 1) > 0) /* 0 signals EOF */ - write(STDOUT_FILENO, &c, 1); /* write one byte to the standard output */ - - /* Release the lock explicitly. */ + /* Now release the lock explicitly. */ lock.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &lock) < 0) report_and_exit("explicit unlocking failed..."); - close(fd); - return 0; + close(fd); /* close the file: would unlock if needed */ + return 0; /* terminating the process would unlock as well */ } ``` @@ -140,8 +135,8 @@ lock.l_type = F_UNLCK; #define FileName "data.dat" void report_and_exit(const char* msg) { - [perror][4](msg); - [exit][5](-1); /* EXIT_FAILURE */ + perror(msg); + exit(-1); /* EXIT_FAILURE */ } int main() { @@ -240,37 +235,37 @@ This is the way the world ends... #include "shmem.h" void report_and_exit(const char* msg) { - [perror][4](msg); - [exit][5](-1); + perror(msg); + exit(-1); } int main() { int fd = shm_open(BackingFile, /* name from smem.h */ - O_RDWR | O_CREAT, /* read/write, create if needed */ - AccessPerms); /* access permissions (0644) */ + O_RDWR | O_CREAT, /* read/write, create if needed */ + AccessPerms); /* access permissions (0644) */ if (fd < 0) report_and_exit("Can't open shared mem segment..."); ftruncate(fd, ByteSize); /* get the bytes */ caddr_t memptr = mmap(NULL, /* let system pick where to put segment */ - ByteSize, /* how many bytes */ - PROT_READ | PROT_WRITE, /* access protections */ - MAP_SHARED, /* mapping visible to other processes */ - fd, /* file descriptor */ - 0); /* offset: start at 1st byte */ + ByteSize, /* how many bytes */ + PROT_READ | PROT_WRITE, /* access protections */ + MAP_SHARED, /* mapping visible to other processes */ + fd, /* file descriptor */ + 0); /* offset: start at 1st byte */ if ((caddr_t) -1 == memptr) report_and_exit("Can't get segment..."); - [fprintf][7](stderr, "shared mem address: %p [0..%d]\n", memptr, ByteSize - 1); - [fprintf][7](stderr, "backing file: /dev/shm%s\n", BackingFile ); + fprintf(stderr, "shared mem address: %p [0..%d]\n", memptr, ByteSize - 1); + fprintf(stderr, "backing file: /dev/shm%s\n", BackingFile ); - /* semahore code to lock the shared mem */ + /* semaphore code to lock the shared mem */ sem_t* semptr = sem_open(SemaphoreName, /* name */ - O_CREAT, /* create the semaphore */ - AccessPerms, /* protection perms */ - 0); /* initial value */ + O_CREAT, /* create the semaphore */ + AccessPerms, /* protection perms */ + 0); /* initial value */ if (semptr == (void*) -1) report_and_exit("sem_open"); - [strcpy][8](memptr, MemContents); /* copy some ASCII bytes to the segment */ + strcpy(memptr, MemContents); /* copy some ASCII bytes to the segment */ /* increment the semaphore so that memreader can read */ if (sem_post(semptr) < 0) report_and_exit("sem_post"); @@ -341,8 +336,8 @@ munmap(memptr, ByteSize); /* unmap the storage * #include "shmem.h" void report_and_exit(const char* msg) { - [perror][4](msg); - [exit][5](-1); + perror(msg); + exit(-1); } int main() { @@ -351,24 +346,24 @@ int main() { /* get a pointer to memory */ caddr_t memptr = mmap(NULL, /* let system pick where to put segment */ - ByteSize, /* how many bytes */ - PROT_READ | PROT_WRITE, /* access protections */ - MAP_SHARED, /* mapping visible to other processes */ - fd, /* file descriptor */ - 0); /* offset: start at 1st byte */ + ByteSize, /* how many bytes */ + PROT_READ | PROT_WRITE, /* access protections */ + MAP_SHARED, /* mapping visible to other processes */ + fd, /* file descriptor */ + 0); /* offset: start at 1st byte */ if ((caddr_t) -1 == memptr) report_and_exit("Can't access segment..."); /* create a semaphore for mutual exclusion */ sem_t* semptr = sem_open(SemaphoreName, /* name */ - O_CREAT, /* create the semaphore */ - AccessPerms, /* protection perms */ - 0); /* initial value */ + O_CREAT, /* create the semaphore */ + AccessPerms, /* protection perms */ + 0); /* initial value */ if (semptr == (void*) -1) report_and_exit("sem_open"); /* use semaphore as a mutex (lock) by waiting for writer to increment it */ if (!sem_wait(semptr)) { /* wait until semaphore != 0 */ int i; - for (i = 0; i < [strlen][6](MemContents); i++) + for (i = 0; i < strlen(MemContents); i++) write(STDOUT_FILENO, memptr + i, 1); /* one byte at a time */ sem_post(semptr); } diff --git a/published/20190416 Inter-process communication in Linux- Using pipes and message queues.md b/published/20190416 Inter-process communication in Linux- Using pipes and message queues.md index f0393a1ba6..714f451e2e 100644 --- a/published/20190416 Inter-process communication in Linux- Using pipes and message queues.md +++ b/published/20190416 Inter-process communication in Linux- Using pipes and message queues.md @@ -87,8 +87,8 @@ world #define WriteEnd 1 void report_and_exit(const char* msg) { - [perror][6](msg); - [exit][7](-1); /** failure **/ + perror(msg); + exit(-1); /** failure **/ } int main() { @@ -112,11 +112,11 @@ int main() { else { /*** parent ***/ close(pipeFDs[ReadEnd]); /* parent writes, doesn't read */ - write(pipeFDs[WriteEnd], msg, [strlen][8](msg)); /* write the bytes to the pipe */ + write(pipeFDs[WriteEnd], msg, strlen(msg)); /* write the bytes to the pipe */ close(pipeFDs[WriteEnd]); /* done writing: generate eof */ wait(NULL); /* wait for child to exit */ - [exit][7](0); /* exit normally */ + exit(0); /* exit normally */ } return 0; } @@ -249,7 +249,7 @@ bye, bye ## ditto ```c #include #include -#include +#include #include #include #include @@ -264,24 +264,24 @@ int main() { const char* pipeName = "./fifoChannel"; mkfifo(pipeName, 0666); /* read/write for user/group/others */ int fd = open(pipeName, O_CREAT | O_WRONLY); /* open as write-only */ - if (fd < 0) return -1; /** error **/ - + if (fd < 0) return -1; /* can't go on */ + int i; for (i = 0; i < MaxLoops; i++) { /* write MaxWrites times */ int j; for (j = 0; j < ChunkSize; j++) { /* each time, write ChunkSize bytes */ int k; int chunk[IntsPerChunk]; - for (k = 0; k < IntsPerChunk; k++) - chunk[k] = [rand][9](); - write(fd, chunk, sizeof(chunk)); + for (k = 0; k < IntsPerChunk; k++) + chunk[k] = rand(); + write(fd, chunk, sizeof(chunk)); } - usleep(([rand][9]() % MaxZs) + 1); /* pause a bit for realism */ + usleep((rand() % MaxZs) + 1); /* pause a bit for realism */ } - close(fd); /* close pipe: generates an end-of-file */ - unlink(pipeName); /* unlink from the implementing file */ - [printf][10]("%i ints sent to the pipe.\n", MaxLoops * ChunkSize * IntsPerChunk); + close(fd); /* close pipe: generates an end-of-stream marker */ + unlink(pipeName); /* unlink from the implementing file */ + printf("%i ints sent to the pipe.\n", MaxLoops * ChunkSize * IntsPerChunk); return 0; } @@ -318,13 +318,12 @@ unlink(pipeName); /* unlink from the implementing file */ #include #include - -unsigned is_prime(unsigned n) { /* not pretty, but gets the job done efficiently */ +unsigned is_prime(unsigned n) { /* not pretty, but efficient */ if (n <= 3) return n > 1; if (0 == (n % 2) || 0 == (n % 3)) return 0; unsigned i; - for (i = 5; (i * i) <= n; i += 6) + for (i = 5; (i * i) <= n; i += 6) if (0 == (n % i) || 0 == (n % (i + 2))) return 0; return 1; /* found a prime! */ @@ -332,25 +331,25 @@ unsigned is_prime(unsigned n) { /* not pretty, but gets the job done efficiently int main() { const char* file = "./fifoChannel"; - int fd = open(file, O_RDONLY); + int fd = open(file, O_RDONLY); if (fd < 0) return -1; /* no point in continuing */ unsigned count = 0, total = 0, primes_count = 0; while (1) { int next; int i; - ssize_t count = read(fd, &next, sizeof(int)); + ssize_t count = read(fd, &next, sizeof(int)); if (0 == count) break; /* end of stream */ else if (count == sizeof(int)) { /* read a 4-byte int value */ total++; if (is_prime(next)) primes_count++; - } + } } close(fd); /* close pipe from read end */ unlink(file); /* unlink from the underlying file */ - [printf][10]("Received ints: %u, primes: %u\n", total, primes_count); + printf("Received ints: %u, primes: %u\n", total, primes_count); return 0; } @@ -434,23 +433,23 @@ ID `qid` 在效果上是消息队列文件描述符的对应物。 #### 示例 5. sender 程序 ```c -#include -#include +#include +#include #include #include #include #include "queue.h" void report_and_exit(const char* msg) { - [perror][6](msg); - [exit][7](-1); /* EXIT_FAILURE */ + perror(msg); + exit(-1); /* EXIT_FAILURE */ } int main() { - key_t key = ftok(PathName, ProjectId); + key_t key = ftok(PathName, ProjectId); if (key < 0) report_and_exit("couldn't get key..."); - - int qid = msgget(key, 0666 | IPC_CREAT); + + int qid = msgget(key, 0666 | IPC_CREAT); if (qid < 0) report_and_exit("couldn't get queue id..."); char* payloads[] = {"msg1", "msg2", "msg3", "msg4", "msg5", "msg6"}; @@ -460,11 +459,11 @@ int main() { /* build the message */ queuedMessage msg; msg.type = types[i]; - [strcpy][11](msg.payload, payloads[i]); + strcpy(msg.payload, payloads[i]); /* send the message */ msgsnd(qid, &msg, sizeof(msg), IPC_NOWAIT); /* don't block */ - [printf][10]("%s sent as type %i\n", msg.payload, (int) msg.type); + printf("%s sent as type %i\n", msg.payload, (int) msg.type); } return 0; } @@ -481,21 +480,21 @@ msgsnd(qid, &msg, sizeof(msg), IPC_NOWAIT); #### 示例 6. receiver 程序 ```c -#include -#include +#include +#include #include #include #include "queue.h" void report_and_exit(const char* msg) { - [perror][6](msg); - [exit][7](-1); /* EXIT_FAILURE */ + perror(msg); + exit(-1); /* EXIT_FAILURE */ } - -int main() { + +int main() { key_t key= ftok(PathName, ProjectId); /* key to identify the queue */ if (key < 0) report_and_exit("key not gotten..."); - + int qid = msgget(key, 0666 | IPC_CREAT); /* access if created already */ if (qid < 0) report_and_exit("no access to queue..."); @@ -504,15 +503,15 @@ int main() { for (i = 0; i < MsgCount; i++) { queuedMessage msg; /* defined in queue.h */ if (msgrcv(qid, &msg, sizeof(msg), types[i], MSG_NOERROR | IPC_NOWAIT) < 0) - [puts][12]("msgrcv trouble..."); - [printf][10]("%s received as type %i\n", msg.payload, (int) msg.type); + puts("msgrcv trouble..."); + printf("%s received as type %i\n", msg.payload, (int) msg.type); } /** remove the queue **/ if (msgctl(qid, IPC_RMID, NULL) < 0) /* NULL = 'no flags' */ report_and_exit("trouble removing queue..."); - - return 0; + + return 0; } ```