当前位置: 首页 > news >正文

大型公司网站建设目标网页标准化对网站开发维护所有者的好处

大型公司网站建设目标,网页标准化对网站开发维护所有者的好处,明星网站开发项目介绍,做网站毕业答辩问题进程是资源封装的单位#xff0c;内存就是进程所封装的资源的一种。一般情况下#xff0c;进程间的内存是相互隔离的#xff0c;也就是说一个进程不能访问另一个进程的内存。如果一个进程想要访问另一个进程的内存#xff0c;那么必须要进过内核这个桥梁#xff0c;这就是…进程是资源封装的单位内存就是进程所封装的资源的一种。一般情况下进程间的内存是相互隔离的也就是说一个进程不能访问另一个进程的内存。如果一个进程想要访问另一个进程的内存那么必须要进过内核这个桥梁这就是共享内存。 在linux中共享内存有3种方式分别是POSIX接口mmap以及system V风格的接口。本文分别介绍这3种共享内存的使用方式。在3种方式中POSIX接口简洁易用是最常使用的system V易用性不是很好很少使用。 另外在工作中共享内存作为一种进程间通信的方式我们很轻易就能想到它的优点减少拷贝次数。但是一项技术有优点同时也必然有局限性共享内存的局限性就是在使用的时候往往需要在进程间做同步进程间同步也会带来性能上的损耗。 1POSIX 1.1/dev/shm POSIX共享内存接口使用了/dev/shm临时文件系统。 在介绍POSIX共享内存接口之前有必要先了解linux下的临时文件系统/dev/shm从名字也能看出来这个文件系统是专门用作共享内存的。从mount显示的信息中可以看出来临时文件系统tmpfs被mount到了/dev/shm下。 这是一个临时文件系统同时也是一个内存文件系统也就是说在这个文件系统上创建的文件都是保存在内存中的而不是保存在磁盘上。可想而知性能会比较高。可以像普通文件系统一样使用临时文件系统打开、读写、关闭、删除、拷贝等操作和普通文件是一样的。但是要注意临时文件系统是保存在内存中的机器重启之后不再存在。 /dev/shm默认大小是机器物理内存的一半 使用df -i /dev/shm可以查看默认的inode个数 修改大小和inode个数比如我想将大小修改为4Ginode个数修改为1000使用如下命令进行修改可以看到修改是生效的。 1.2example 如下例子是linux文档中的例子通过man shm_open可以看到这个例子。从例子的实现可以看出来共享内存依赖项有两个一个是/dev/shm临时文件系统一个是mmap。mmap本身就是一种共享内存的方式。所以说POSIX共享内存和mmap并不是完全割裂的前者依赖于后者。其实我们也可以完全不使用shm_open、shm_unlink接口而是直接使用mmap在/dev/shm下创建共享内存也是可以的。 pshm_ucase_bounce.c和pshm_ucase_send.c中分别创建共享内存大小是struct shmbuf的大小。后者向内存中写hello前者将hello改成大写的然后后者打印数据。 pshm_ucase.h #include sys/mman.h #include fcntl.h #include semaphore.h #include sys/stat.h #include stdio.h #include stdlib.h #include unistd.h#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \} while (0)#define BUF_SIZE 1024 /* Maximum size for exchanged string *//* Define a structure that will be imposed on the sharedmemory object */struct shmbuf {sem_t sem1; /* POSIX unnamed semaphore */sem_t sem2; /* POSIX unnamed semaphore */size_t cnt; /* Number of bytes used in buf */char buf[BUF_SIZE]; /* Data being transferred */ };pshm_ucase_bounce.c #include ctype.h #include pshm_ucase.hint main(int argc, char *argv[]) {if (argc ! 2) {fprintf(stderr, Usage: %s /shm-path\n, argv[0]);exit(EXIT_FAILURE);}char *shmpath argv[1];/* Create shared memory object and set its size to the sizeof our structure */printf(size:%d\n, sizeof(struct shmbuf));int fd shm_open(shmpath, O_CREAT | O_EXCL | O_RDWR,S_IRUSR | S_IWUSR);if (fd -1)errExit(shm_open);if (ftruncate(fd, sizeof(struct shmbuf)) -1)errExit(ftruncate);/* Map the object into the callers address space */struct shmbuf *shmp mmap(NULL, sizeof(*shmp),PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);if (shmp MAP_FAILED)errExit(mmap);/* Initialize semaphores as process-shared, with value 0 */if (sem_init(shmp-sem1, 1, 0) -1)errExit(sem_init-sem1);if (sem_init(shmp-sem2, 1, 0) -1)errExit(sem_init-sem2);/* Wait for sem1 to be posted by peer before touchingshared memory */if (sem_wait(shmp-sem1) -1)errExit(sem_wait);/* Convert data in shared memory into upper case */for (int j 0; j shmp-cnt; j)shmp-buf[j] toupper((unsigned char) shmp-buf[j]);/* Post sem2 to tell the to tell peer that it can nowaccess the modified data in shared memory */if (sem_post(shmp-sem2) -1)errExit(sem_post);/* Unlink the shared memory object. Even if the peer processis still using the object, this is okay. The object willbe removed only after all open references are closed. */shm_unlink(shmpath);exit(EXIT_SUCCESS); } pshm_ucase_send.c #include string.h #include pshm_ucase.hint main(int argc, char *argv[]) {if (argc ! 3) {fprintf(stderr, Usage: %s /shm-path string\n, argv[0]);exit(EXIT_FAILURE);}char *shmpath argv[1];char *string argv[2];size_t len strlen(string);if (len BUF_SIZE) {fprintf(stderr, String is too long\n);exit(EXIT_FAILURE);}/* Open the existing shared memory object and map itinto the callers address space */int fd shm_open(shmpath, O_RDWR, 0);if (fd -1)errExit(shm_open);struct shmbuf *shmp mmap(NULL, sizeof(*shmp),PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);if (shmp MAP_FAILED)errExit(mmap);/* Copy data into the shared memory object */shmp-cnt len;memcpy(shmp-buf, string, len);/* Tell peer that it can now access shared memory */if (sem_post(shmp-sem1) -1)errExit(sem_post);/* Wait until peer says that it has finished accessingthe shared memory */if (sem_wait(shmp-sem2) -1)errExit(sem_wait);/* Write modified data in shared memory to standard output */write(STDOUT_FILENO, shmp-buf, len);write(STDOUT_FILENO, \n, 1);exit(EXIT_SUCCESS); } 2mmap mmap在linux中是经常使用的mmap不仅仅可以用来共享内存当我们使用malloc申请内存时默认情况下如果申请的内存大于128K那么底层便会使用mmap来从系统申请内存mmap同样也可以将系统的设备内存映射到用户态。 void *mmap(void *addr, size_t length, int prot, int flags,                   int fd, off_t offset); MAP_SHARED共享一个进程修改之后另一个进程能看到。如果我们要使用共享内存那么需要设置这个标志MAP_PRIVATE 私有也就是不共享即使两个进程使用mmap映射的是同一个文件偏移量都是一样的那么一个进程的修改另一个进程也看不到。 从下边的注释可以看到设置MAP_PRIVATE使用copy on write机制当一个进程要写的时候进程内会拷贝一份。另外私有的情况下数据最终会不会保存到文件中是不确定的。 MAP_ANONYMOUS匿名映射mmap的倒数第二个参数是一个fd如果要进行文件映射那么需要首先打开这个文件再使用mmap进行映射如果是匿名映射那么就不需要指定fd将fd设置为-1即可。 匿名映射常常用于父子进程间的内存共享文件映射常常用于没有父子关系的进程间的内存共享。 如果我们想要内存中的内容会保存到一个文件中并且开机之后还能够使用那么就必须使用共享和文件映射的方式。 2.1文件映射 文件映射就是要基于文件系统的一个文件来映射第一节中的POSIX接口就是使用的临时文件系统中的文件进行映射。如下两个文件aa.c和bb.c编译之后先运行aa再运行bb可以看到aa写的数据bb能够读到bb写的数据aa也能读到。 aa.c #include stdio.h #include stdlib.h #include fcntl.h #include sys/mman.h #include unistd.h #include string.hint main() {const char *filename ./shared_file.txt;const size_t length 100;int fd open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666);ftruncate(fd, length);char *shared_mem mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);close(fd);if (shared_mem MAP_FAILED) {perror(mmap);return 1;}strcpy(shared_mem, Hello from aa!);printf(after aa write\n);sleep(5);printf(aa read:%s\n, shared_mem);munmap(shared_mem, length);return 0; }bb.c #include stdio.h #include stdlib.h #include fcntl.h #include sys/mman.h #include unistd.h #include string.hint main() {const char *filename ./shared_file.txt;const size_t length 100;int fd open(filename, O_RDWR, 0666);char *shared_mem mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);close(fd);if (shared_mem MAP_FAILED) {perror(mmap);return 1;}printf(bb read:%s\n, shared_mem);strcpy(shared_mem, Hello from bb!);munmap(shared_mem, length);return 0; }2.2匿名映射 匿名映射可以用于父子进程间的内存共享如下是一个例子。 ①父进程中首先向共享内存中写Hello from parent! ②父进程调用fork创建子进程 ③子进程读取内存中的内容然后向内存中写数据“Hello from child!” ④父进程等待子进程退出然后读取共享内存中的数据 #include stdio.h #include stdlib.h #include sys/mman.h #include unistd.h #include string.hint main() {// 创建匿名共享内存size_t length 100;char *shared_mem mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);if (shared_mem MAP_FAILED) {perror(mmap);return 1;}strcpy(shared_mem, Hello from parent!);pid_t pid fork(); // 创建子进程if (pid 0) {// 子进程printf(child read:%s\n, shared_mem);strcpy(shared_mem, Hello from child!);printf(child write:%s\n, shared_mem);} else {// 父进程wait(NULL); // 等待子进程结束printf(parent read:%s\n, shared_mem); // 读取共享内存内容}munmap(shared_mem, length); // 解除映射return 0; }运行结果如下从结果可以看出来子进程写的数据父进程可以读出来说明内存在父子进程之间是共享的。 如果把mmap中的标志MAP_SHARED改为MAP_PRIVATE那么内存在父子进程间是不共享的。子进程写数据之后父进程也看不到父进程中读出来还是“Hello from parent!”。这个时候内存在父进程和子进程中各有一份。MAP_PRIVATE下使用写时拷贝的机制只有写的时候才会分配一份内存读的时候不会所以在子进程中一开始读内存中数据的时候还能看到一开始父进程写的数据。 2.3查看文件映射和匿名映射 /pro/pid/maps中显式了进程的内存映射。 只有在共享映射的时候才能在maps文件中看到对应的映射私有映射的时候看不到。 如下是文件映射可以看到shared_file.txt映射的内存范围。 如下是匿名映射可以看到匿名映射映射的是/dev/zero。 2.4mmap使用注意问题 2.4.1offset应为PAGE_SIZE的整数倍 mmap的最后一个形参offset需要是页大小的整数倍页大小通过sysconf(_SC_PAGE_SIZE)来获取。如果offset不是页的整数倍那么会返回错误Invalid argument。本人测试无论是文件映射还是匿名映射MAP_SHARED还是MAP_PRIVATE这条限制都存在。 2.4.2文件映射时映射的内存不能超过文件的大小 当使用文件映射时如果映射的内存的大小大于文件本身的大小那么在调用mmap时并不会返回错误但是在写数据的时候会出现段错误。 如下代码如果shared_file.txt是不存在的那么调用open的时候会创建该文件默认大小是0。不调用ftruncate直接调用mmap映射的内存大小是100这个时候mmap不会返回错误但是在写内存的时候会出现段错误。所以在使用mmap映射文件的时候必须要保证offsetlength的数据不超过文件的大小才可以。ftruncate可以设置文件的大小。 #include stdio.h #include stdlib.h #include fcntl.h #include sys/mman.h #include unistd.h #include string.hint main() {const char *filename ./shared_file.txt;const size_t length 100;int fd open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666);// ftruncate(fd, length);char *shared_mem mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);close(fd);if (shared_mem MAP_FAILED) {perror(mmap);return 1;}strcpy(shared_mem, Hello from aa!);printf(after aa write\n);sleep(5);printf(aa read:%s\n, shared_mem);munmap(shared_mem, length);return 0; }3system V systemV类型的共享内存要使用4个api。 ①首先要使用ftok来获取一个key ②使用shmget获取一个id ③使用shmat获取共享内存的地址 ④共享内存使用完毕之后使用shmdt删除共享内存 writer.c #include stdio.h #include stdlib.h #include sys/ipc.h #include sys/shm.h #include string.h #include unistd.h#define SHM_SIZE 100 // 共享内存大小int main() {key_t key ftok(./shmfile, 65); // 创建一个唯一的键int shmid shmget(key, SHM_SIZE, 0666 | IPC_CREAT); // 获取共享内存段if (shmid 0) {perror(shmget);return 1;}char *str (char *)shmat(shmid, NULL, 0); // 将共享内存附加到当前进程地址空间if (str (char *)(-1)) {perror(shmat);return 1;}// 向共享内存写入数据strcpy(str, Hello from writer!);printf(Writer wrote: %s\n, str);sleep(20);shmdt(str); // 解除共享内存return 0; }reader.c #include stdio.h #include stdlib.h #include sys/ipc.h #include sys/shm.h #include string.h #include unistd.h#define SHM_SIZE 100 // 共享内存大小int main() {key_t key ftok(./shmfile, 65); // 创建一个唯一的键int shmid shmget(key, SHM_SIZE, 0666); // 获取共享内存段if (shmid 0) {perror(shmget);return 1;}char *str (char *)shmat(shmid, NULL, 0); // 将共享内存附加到当前进程地址空间if (str (char *)(-1)) {perror(shmat);return 1;}// 读取共享内存内容printf(Reader read: %s\n, str);shmdt(str); // 解除共享内存return 0; }如果共享内存只是在父子进程间共享那么不需要使用ftok通过文件来获取一个key在使用shmget的时候直接使用IPC_PRIVATE即可。如下是一个例子在父子进程间共享内存。 #include stdio.h #include stdlib.h #include sys/ipc.h #include sys/shm.h #include string.h #include unistd.h#define SHM_SIZE 100 // 共享内存大小int main() {int shmid shmget(IPC_PRIVATE, SHM_SIZE, 0666 | IPC_CREAT); // 获取共享内存段if (shmid 0) {perror(shmget);exit(1);}// 创建子进程pid_t pid fork();if (pid 0) {perror(fork);exit(1);}if (pid 0) {// 父进程char *str (char *)shmat(shmid, NULL, 0); // 将共享内存附加到父进程if (str (char *)(-1)) {perror(shmat);exit(1);}// 向共享内存写入数据strcpy(str, Hello from parent!);printf(Parent wrote: %s\n, str);sleep(4);printf(Parent read: %s\n, str);shmdt(str); // 解除共享内存wait(NULL); // 等待子进程结束} else {// 子进程sleep(1); // 等待父进程写入数据char *str (char *)shmat(shmid, NULL, 0); // 将共享内存附加到子进程if (str (char *)(-1)) {perror(shmat);exit(1);}// 读取共享内存内容printf(Child read: %s\n, str);strcpy(str, Hello from child!);printf(child wrote: %s\n, str);shmdt(str); // 解除共享内存}// 删除共享内存段if (pid 0) {shmctl(shmid, IPC_RMID, NULL); // 只有父进程删除共享内存}return 0; }
http://www.w-s-a.com/news/150215/

相关文章:

  • 男女做暖暖的网站大全深圳平台网站建设外包
  • 凯里展示型网站设计抖音代运营收费详细价格
  • 外包网站会自己做原型吗网站制作怎样盈利
  • 为什么在百度搜不到我的网站电商网站开发过程
  • 什么是网站反链网页设计页面链接
  • 佛山企业网站制作韩国seocaso
  • 微信公司网站vue做社区网站
  • 蒙阴网站优化五核网站建设
  • 企业微商城网站建设wordpress新闻是哪个表
  • 重庆网站开发培训机构电商网站创办过程
  • 企业建网站得多少钱长沙财优化公司
  • 网站开发api平台扒完网站代码之后怎么做模板
  • PHP网站建设选择哪家好动画设计师月薪多少
  • 网站如何做市场推广网站开发主要步骤
  • 浏览器正能量网站网页文章导入wordpress
  • 江西中国建设银行网站首页永久免费自助建网站
  • 创建自己网站的步骤吸引人的微信软文
  • 网站建设与网页设计论述题软件开发公司在哪里
  • 二级网站建设方案模板亚马逊网站建设案例
  • 网站开发兼职团队门户网站如何制作
  • 高州市网站建设开发区招聘信息
  • 上海专业网站制作设计公司企业邮箱怎样注册
  • 网站建设在商标第几类网站建设 设计创意
  • 做一网站APP多少钱重庆中色十二冶金建设有限公司网站
  • 网上做效果图网站有哪些软件徐州泉山区建设局网站
  • 凯里网站制作网站篡改搜索引擎js
  • 如何使用凡科建设网站武安城乡建设网站
  • 网站建设网站及上传wordpress火车头发布
  • 有没有做网站的团队电脑版传奇网站
  • 建立企业网站公司医疗创意小产品设计