mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
commit
766e573bac
@ -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。
|
||||
|
@ -62,47 +62,42 @@ producer-------->| disk file |<-------consumer
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
@ -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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
@ -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 <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
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 <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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 <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <stdlib.h>
|
||||
#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;
|
||||
}
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user