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

甘肃住房建设厅的网站百度竞价排名算法

甘肃住房建设厅的网站,百度竞价排名算法,asp做的网站缺点,php怎样做网站的注删页面共享内存 OVERVIEW共享内存一、文件上锁flock二、共享内存1.关联共享内存ftok2.获取共享内存shmget3.绑定共享内存shmat4.绑定分离shmdt5.控制共享内存shmctl三、亲缘进程间通信1.共享内存写入与读取2.共享内存解绑与删除3.共享内存综合四、非亲缘进程间通信1.通过sleep同步2.通…

共享内存


OVERVIEW

  • 共享内存
      • 一、文件上锁flock
      • 二、共享内存
        • 1.关联共享内存ftok
        • 2.获取共享内存shmget
        • 3.绑定共享内存shmat
        • 4.绑定分离shmdt
        • 5.控制共享内存shmctl
      • 三、亲缘进程间通信
        • 1.共享内存写入与读取
        • 2.共享内存解绑与删除
        • 3.共享内存综合
      • 四、非亲缘进程间通信
        • 1.通过sleep同步
        • 2.通过条件变量同步

一、文件上锁flock

可以利用flock系统调用实现,当有一个进程在文件中进程写入操作时,其他进程无法在该文件中进行写操作(只能进行读操作)。

  • 多进程实现前n项数求和(利用flock实现)
#include "head.h"struct data {int now;//中间结果int sum;//求和结果
};void getnum(struct data *d) {int fd;if ((fd = open(".data", O_RDONLY)) < 0) {perror("setopen");exit(1);}read(fd, (void *)d, sizeof(struct data));close(fd);
}void setnum(struct data *d) {int fd;if ((fd = open(".data", O_RDWR | O_CREAT, 0600)) < 0) {//只有文件的所属用户(当前的进程)有访问以及写的权限perror("getopen");exit(1);}write(fd, (void *)d, sizeof(struct data));close(fd);
}void doSum(struct data *d, int max, int i) {int fd_lock;//将lock标志给到某个文件上(.lock) 通过该文件判断进程是否有资格打开另一个被保护的文件(.data)if ((fd_lock = open(".lock", O_RDONLY)) < 0) {perror("lockopen");exit(1);}while (1) {//计算的过程需要上锁flock(fd_lock, LOCK_EX);//加锁(加锁后其他进程后面计算的语句将无法执行)getnum(d);//从.data取出上个结果if (d->now >= max) break;//判断 计算结果d->now++;d->sum += d->now;setnum(d);//将计算的结果放回.dataprintf("<i am the %dth child> now = %d, sum = %d\n", i, d->now, d->sum);flock(fd_lock, LOCK_UN);//为解锁}close(fd_lock);
}int main(int argc, char *argv[]) {//多进程实现求前n项和 同一时刻只有一个进程持有该文件//计算从0到n的和 m个进程//a.out -i -n nint opt;int ins = 1, max = 100;struct data d;d.now = 0;d.sum = 0;setnum(&d);while ((opt = getopt(argc, argv, "i:n:")) != -1) {switch (opt) {case 'i':ins = atoi(optarg);break;case 'n':max = atoi(optarg);break;default:fprintf(stderr, "Usage : %s -i num1 -n num2", argv[0]);exit(1);}}int i;pid_t pid;for (i = 0; i < ins; ++i) {//创建ins个进程对文件进行doSum操作if ((pid = fork()) < 0) {perror("fork()");exit(1);}if (pid == 0) break;}if (pid == 0) {doSum(&d, max, i);} else {for (int k = 0; k < ins; ++k) wait(NULL);}return 0;
}

image-20230224210120883

二、共享内存

允许两个或多个进程共享一个给定的存储区,由于无需复制数据,这是最快的IPC进程间通信。

1.关联共享内存ftok

image-20230224215755103

#include "head.h"int main() {//ftok将projectId与文件名字转换为键值对key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);printf("123 = 0x%x\n", 123);return 0;
}

image-20230224215900200

2.获取共享内存shmget

image-20230224212406973

#include "head.h"int main() {//1.申请一块共享内存 将projectId与文件名字转换为 共享内存键值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根据共享内存对应的key值 和内存大小size 得到共享内存的标识符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);return 0;
}

image-20230224221845280

3.绑定共享内存shmat

image-20230225230606913

#include "head.h"int main() {//1.申请一块共享内存 将projectId与文件名字转换为 共享内存键值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根据共享内存对应的key值 和内存大小size 得到共享内存的标识符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);//3.将进程的动态内存空间和 共享内存空间关联void *shmemory = NULL;if ((shmemory = shmat(shmid, NULL, 0)) == (void*)-1) {perror("shmat");exit(1);}sleep(10);return 0;
}

image-20230225232517349

4.绑定分离shmdt

image-20230225232744715

#include "head.h"int main() {//1.申请一块共享内存 将projectId与文件名字转换为 共享内存键值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根据共享内存对应的key值 和内存大小size 得到共享内存的标识符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);//3.将进程的动态内存空间和 共享内存空间关联void *shmemory = NULL;if ((shmemory = shmat(shmid, NULL, 0)) == (void*)-1) {perror("shmat");exit(1);}//4.将进程的动态内存空间和 共享内存空间关联解除int flag;if ((flag = shmdt(shmemory)) < 0) {perror("shmdt");exit(1);}return 0;
}

5.控制共享内存shmctl

image-20230226002223768

#include "head.h"int main() {//1.申请一块共享内存 将projectId与文件名字转换为 共享内存键值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根据共享内存对应的key值 和内存大小size 得到共享内存的标识符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);//3.将进程的动态内存空间和 共享内存空间关联void *shmemory = NULL;if ((shmemory = shmat(shmid, NULL, 0)) == (void*)-1) {perror("shmat");exit(1);}//4.将进程的动态内存空间和 共享内存空间关联解除int flag;if ((flag = shmdt(shmemory)) < 0) {perror("shmdt");exit(1);}//5.shmctl删除共享内存空间if ((flag = shmctl(shmid, IPC_RMID, NULL)) < 0) {perror("shmctl");exit(1);}return 0;
}

三、亲缘进程间通信

1.共享内存写入与读取

#include "head.h"//共享内存综合运用
int main() {key_t key;int shmid;pid_t pid;char *shmemory = NULL;//1.开辟一块共享内存空间//(1)申请一块共享内存 将projectId与文件名字转换为 共享内存键值if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}//(2)根据共享内存对应的key值 和内存大小size 得到共享内存的标识符if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}//(3)将进程的动态内存空间和 共享内存空间关联if ((shmemory = shmat(shmid, NULL, 0)) == (void *)-1) {perror("shmat");exit(1);}//2.创建子进程 进行运算操作if ((pid = fork()) < 0) {perror("fork");exit(1);}if (pid) {//父进程写入while(1) {printf("i am the father : \n");scanf("%[^\n]s", shmemory);//向共享内存中写入getchar();//吞掉回车否则不停循环sleep(2);}} else {//子进程读出while (1) {sleep(1);if (strlen(shmemory)) printf("i am the child : %s\n", shmemory);//如果共享内存空间中有数据才进行输出memset(shmemory, 0, 4096);//临时清空共享存储空间}}return 0;
}

image-20230228214143422

2.共享内存解绑与删除

#include "head.h"//共享内存综合运用
int main() {key_t key;int shmid;pid_t pid;char *shmemory = NULL;//1.开辟一块共享内存空间//(1)申请一块共享内存 将projectId与文件名字转换为 共享内存键值if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}//(2)根据共享内存对应的key值 和内存大小size 得到共享内存的标识符if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}//(3)将进程的动态内存空间和 共享内存空间关联if ((shmemory = shmat(shmid, NULL, 0)) == (void *)-1) {perror("shmat");exit(1);}//2.创建子进程 利用shmdt实现 一次读取一次读入操作if ((pid = fork()) < 0) {perror("fork");exit(1);}if (pid) {printf("i am the father : \n");scanf("%[^\n]s", shmemory);getchar();} else {sleep(5);if (strlen(shmemory)) printf("i am the child : %s\n", shmemory);memset(shmemory, 0, 4096);}//3.删除开辟的共享内存空间//(1)将进程的动态内存空间和 共享内存空间关联解除int flag;if ((flag = shmdt(shmemory)) < 0) {perror("shmdt");exit(1);}//(2)shmctl删除共享内存空间(父进程执行)if (pid) {wait(NULL);if ((flag = shmctl(shmid, IPC_RMID, NULL)) < 0) {perror("shmctl");exit(1);}}sleep(5);return 0;
}

image-20230228215903113

3.共享内存综合

  • 利用共享内存实现多进程前n项数求和(利用共享内存实现)
#include "head.h"struct data {int now;//中间结果int sum;//求和结果
};void doSum(struct data *d, int max, int i) {while (1) {//计算的过程需要上锁if (d->now >= max) break;//判断 计算结果d->now++;d->sum += d->now;printf("<i am the %dth child> now = %d, sum = %d\n", i, d->now, d->sum);}
}int main(int argc, char *argv[]) {//1.命令行解析 a.out -i -n nint opt;int ins = 1, max = 100;// struct data d;// d.now = 0;// d.sum = 0;// setnum(&d);while ((opt = getopt(argc, argv, "i:n:")) != -1) {switch (opt) {case 'i':ins = atoi(optarg);break;case 'n':max = atoi(optarg);break;default:fprintf(stderr, "Usage : %s -i num1 -n num2", argv[0]);exit(1);}}//2.共享内存的创建于绑定key_t key;int shmid;struct data *shmemory = NULL;//2.1申请一块共享内存 将projectId与文件名字转换为 共享内存键值if ((key = ftok("5.shm_sum.c", 123)) == -1) {perror("ftok");exit(1);}//2.2根据共享内存对应的key值 和内存大小size 得到共享内存的标识符if ((shmid = shmget(key, sizeof(struct data), IPC_CREAT | 0600)) < 0) {perror("shmget");exit(1);}//2.3将进程的动态内存空间和 共享内存空间关联if ((shmemory = (struct data *)shmat(shmid, NULL, 0)) == (struct data *)-1) {perror("shmat");exit(1);}shmemory->now = 0;shmemory->sum = 0;//3.创建ins个子进程对文件进行doSum操作int i;pid_t pid;for (i = 0; i < ins; ++i) {if ((pid = fork()) < 0) {perror("fork()");exit(1);}if (pid == 0) break;}if (pid == 0) {doSum(shmemory, max, i);} else {for (int k = 0; k < ins; ++k) wait(NULL);printf("%d\n", shmemory->sum);}return 0;
}

image-20230228223341746

image-20230228223606341

成功输出结果,前100项求和的结果为5050,但是当使用程序求前10000项和时,却会出现问题如图结果为50007661(错误结果)。

image-20230228223444201

出现问题的原因是:执行中的进程没有保障,进程之间发生竞争(同一时刻多个进程对内存进行读写操作,发生在多核处理器)

可以利用条件变量实现线程同步机制(进程同步),从而避免资源抢占竞争。

四、非亲缘进程间通信

共享内存实现多进程计算,

  1. 单核不考虑同步关系,可以正常实现
  2. 多核不考虑同步关系,无法正常实现
  3. 需要设置同步关系
  4. 利用条件变量实现进程同步

非亲缘进程之间的通信,

1.通过sleep同步

  • 使用共享内存实现两个非亲缘关系进程(1号进程、2号进程)进行通话
  • 1号进程只输出2号进程在共享内存中输入的数据
  • 2号进程只输出1号进程在共享内存中输入的数据
  • 同步(通过sleep实现同步)
#include "head.h"struct SHM {int flag;//SHM能否读写int type;//第几个进程char mesg[50];//输入的信息
};int main(int argc, char *argv[]) {//1.命令行解析 ./a.out -t 1|2 -m messageint opt;int type;char mesg[50];struct SHM *temp;//用于临时存放准备写入共享内存的数据if (argc != 5) {fprintf(stderr, "Usage : %s -t 1|2 -m message\n", argv[0]);exit(1);}while ((opt = getopt(argc, argv, "t:m:")) != -1) {switch (opt) {case 't':type = atoi(optarg);break;case 'm':strcpy(mesg, optarg);break;default:fprintf(stderr, "Usage : %s -t 1|2 -m message\n", argv[0]);exit(1);}}/***存在问题*为什么直接在switch中使用 temp->type = atoi(optarg); 会出现segmentfault呢?*必须使用临时变量 int type; 来转接数据才不会报错? */temp->type = type;strcpy(temp->mesg, mesg);//2.共享内存的创建与绑定key_t key;int shmid;struct SHM *shmemory = NULL;//2.1申请一块共享内存 将projectId与文件名字转换为 共享内存键值if ((key = ftok("1.shm_my.c", 123)) == -1) {perror("ftok");exit(1);}//2.2根据共享内存对应的key值 和内存大小size 得到共享内存的标识符if ((shmid = shmget(key, sizeof(struct SHM), IPC_CREAT | IPC_EXCL | 0600)) < 0) {if (errno == EEXIST) {//处理重复创建共享内存空间if ((shmid = shmget(key, sizeof(struct SHM), 0600)) < 0) {perror("shmget1");exit(1);}printf("shmemory exist!");} else {perror("shmget2");exit(1);}}//2.3将进程的动态内存空间和 共享内存空间关联if ((shmemory = (struct SHM *)shmat(shmid, NULL, 0)) == (struct SHM *)-1) {perror("shmat");exit(1);}//3.实现非亲缘进程间通信shmemory->flag = 0;//初始状态为允许写入while (1) {if (!shmemory->flag) {printf("<Process%d> : i get shmemory\n", temp->type);sprintf(shmemory->mesg, "<Process%d> : <%s>", temp->type, temp->mesg);//向共享内存中写入内容shmemory->flag = 1;sleep(1);} else {printf("%s\n", shmemory->mesg);//从共享内存中读取 并输出内容shmemory->flag = 0;}}return 0;
}

image-20230301103041419

2.通过条件变量同步

思考:如何通过条件变量以及互斥锁,通过共享内存空间实现多进程同步

  • 一个进程1号进程,作为主要发送进程
  • 多个进程,输出1号进程发送的数据
  • 利用条件变量和互斥锁实现同步

image-20230301110138124

#include "head.h"struct SHM {int type;//第几个进程char mesg[50];//输入的信息pthread_mutex_t mutex;//互斥锁pthread_cond_t cond;//条件变量
};int main(int argc, char *argv[]) {//1.命令行解析 ./a.out -t 1|2int opt;int type;if (argc != 3) {fprintf(stderr, "Usage : %s -t 1|2\n", argv[0]);exit(1);}while ((opt = getopt(argc, argv, "t:")) != -1) {switch (opt) {case 't':type = atoi(optarg);break;default:fprintf(stderr, "Usage : %s -t 1|2\n", argv[0]);exit(1);}}//2.共享内存的创建与绑定key_t key;int shmid;struct SHM *shmemory = NULL;//2.1申请一块共享内存 将projectId与文件名字转换为 共享内存键值if ((key = ftok("2.shm_cond.c", 123)) == -1) {perror("ftok");exit(1);}//2.2根据共享内存对应的key值 和内存大小size 得到共享内存的标识符if ((shmid = shmget(key, sizeof(struct SHM), IPC_CREAT | IPC_EXCL | 0600)) < 0) {if (errno == EEXIST) {//处理重复创建共享内存空间if ((shmid = shmget(key, sizeof(struct SHM), 0600)) < 0) {perror("shmget1");exit(1);}printf("shmemory exist!\n");} else {perror("shmget2");exit(1);}}//2.3将进程的动态内存空间和 共享内存空间关联if ((shmemory = (struct SHM *)shmat(shmid, NULL, 0)) == (struct SHM *)-1) {perror("shmat");exit(1);}//3.实现非亲缘进程间通信if (type == 1) {//让1号进程初始化互斥锁和信号量 并设为共享pthread_mutexattr_t mutex;pthread_condattr_t cond;pthread_mutexattr_init(&mutex);pthread_condattr_init(&cond);pthread_mutexattr_setpshared(&mutex, 1);//设置为共享pthread_condattr_setpshared(&cond, 1);//设置为共享pthread_mutex_init(&shmemory->mutex, &mutex);//初始化锁pthread_cond_init(&shmemory->cond, &cond);//初始化条件}if (type == 1) {while (1) {printf("ok\n");scanf("%[^\n]s", shmemory->mesg); getchar();if (strlen(shmemory->mesg)) pthread_cond_signal(&shmemory->cond);//1号进程写入后通知其他进程}} else {while (1) {pthread_mutex_lock(&shmemory->mutex);//一旦有某个进程拿到了共享内存 则将共享内存上锁pthread_cond_wait(&shmemory->cond, &shmemory->mutex);//共享内存上锁后 等待1号进程写入完成的通知//if (strlen(shmemory->mesg)) printf("<Process%d> : %s\n", type, shmemory->mesg);//将共享内存中写入的数据输出memset(shmemory->mesg, 0, strlen(shmemory->mesg));//清空共享内存pthread_mutex_unlock(&shmemory->mutex);}}return 0;
}

image-20230301171032340

http://www.qdjiajiao.com/news/12877.html

相关文章:

  • 东莞最新网站建设软件电脑优化软件哪个好用
  • discuz是什么东西搜索引擎优化的方法有哪些?
  • 旅游网站项目评估微信推广软件哪个好
  • 网站源码带采集营业推广的方式
  • 还有哪些网站可以做淘宝活动发稿服务
  • 重庆建设工程安全网百度搜索优化软件
  • 招工网站怎么做河北百度seo
  • 天津河东做网站公司谷歌安装器
  • 日本新冠肺炎疫情最新情况成都seo网络优化公司
  • 专门做网站开发的公司购买域名后如何建立网站
  • discuz 分类网站志鸿优化网官网
  • 网站核检单免费访问国外网站的app
  • 推荐一个两学一做的网站什么平台发广告最有效
  • 南山商城网站建设哪家公司靠谱网络推广怎么做
  • 上海市区网站设计制作公司北京中文seo
  • 青岛网站搜索排名网络营销与策划
  • 织梦做的网站打不开网页达内教育
  • 沈阳定制网站制作软文广告属于什么营销
  • html5结构的网站百度百家号注册
  • 佛山网站建设 奇锐科技广告推广的软件
  • 网站集约化建设什么意思廊坊seo外包公司费用
  • 海宁网站建设公司推荐上海百度竞价点击软件
  • 广州市公司网站建设价格郑州seo询搜点网络效果佳
  • 网站模板但没有后台如何做网站steam交易链接怎么获取
  • 网站开发中的著作权归属医院线上预约
  • 网站建设技术线路选择成都网站seo技巧
  • 网站推广怎么优化301313龙虎榜
  • 芜湖住房和城乡建设委员会网站自己创建一个网站需要多少钱
  • 加强政府门户网站建设通知网站seo属于什么专业
  • wordpress 主题翻译重庆网站seo好不好