中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

甘肅住房建設(shè)廳的網(wǎng)站評論優(yōu)化

甘肅住房建設(shè)廳的網(wǎng)站,評論優(yōu)化,電子商務(wù)網(wǎng)站建設(shè)與規(guī)劃總結(jié),上海網(wǎng)站建設(shè)專業(yè)公司共享內(nèi)存 OVERVIEW共享內(nèi)存一、文件上鎖flock二、共享內(nèi)存1.關(guān)聯(lián)共享內(nèi)存ftok2.獲取共享內(nèi)存shmget3.綁定共享內(nèi)存shmat4.綁定分離shmdt5.控制共享內(nèi)存shmctl三、親緣進(jìn)程間通信1.共享內(nèi)存寫入與讀取2.共享內(nèi)存解綁與刪除3.共享內(nèi)存綜合四、非親緣進(jìn)程間通信1.通過sleep同步2.通…

共享內(nèi)存


OVERVIEW

  • 共享內(nèi)存
      • 一、文件上鎖flock
      • 二、共享內(nèi)存
        • 1.關(guān)聯(lián)共享內(nèi)存ftok
        • 2.獲取共享內(nèi)存shmget
        • 3.綁定共享內(nèi)存shmat
        • 4.綁定分離shmdt
        • 5.控制共享內(nèi)存shmctl
      • 三、親緣進(jìn)程間通信
        • 1.共享內(nèi)存寫入與讀取
        • 2.共享內(nèi)存解綁與刪除
        • 3.共享內(nèi)存綜合
      • 四、非親緣進(jìn)程間通信
        • 1.通過sleep同步
        • 2.通過條件變量同步

一、文件上鎖flock

可以利用flock系統(tǒng)調(diào)用實(shí)現(xiàn),當(dāng)有一個進(jìn)程在文件中進(jìn)程寫入操作時,其他進(jìn)程無法在該文件中進(jìn)行寫操作(只能進(jìn)行讀操作)。

  • 多進(jìn)程實(shí)現(xiàn)前n項(xiàng)數(shù)求和(利用flock實(shí)現(xiàn))
#include "head.h"struct data {int now;//中間結(jié)果int sum;//求和結(jié)果
};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) {//只有文件的所屬用戶(當(dāng)前的進(jìn)程)有訪問以及寫的權(quán)限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標(biāo)志給到某個文件上(.lock) 通過該文件判斷進(jìn)程是否有資格打開另一個被保護(hù)的文件(.data)if ((fd_lock = open(".lock", O_RDONLY)) < 0) {perror("lockopen");exit(1);}while (1) {//計(jì)算的過程需要上鎖flock(fd_lock, LOCK_EX);//加鎖(加鎖后其他進(jìn)程后面計(jì)算的語句將無法執(zhí)行)getnum(d);//從.data取出上個結(jié)果if (d->now >= max) break;//判斷 計(jì)算結(jié)果d->now++;d->sum += d->now;setnum(d);//將計(jì)算的結(jié)果放回.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[]) {//多進(jìn)程實(shí)現(xiàn)求前n項(xiàng)和 同一時刻只有一個進(jìn)程持有該文件//計(jì)算從0到n的和 m個進(jìn)程//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) {//創(chuàng)建ins個進(jìn)程對文件進(jìn)行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

二、共享內(nèi)存

允許兩個或多個進(jìn)程共享一個給定的存儲區(qū),由于無需復(fù)制數(shù)據(jù),這是最快的IPC進(jìn)程間通信。

1.關(guān)聯(lián)共享內(nèi)存ftok

image-20230224215755103

#include "head.h"int main() {//ftok將projectId與文件名字轉(zhuǎn)換為鍵值對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.獲取共享內(nèi)存shmget

image-20230224212406973

#include "head.h"int main() {//1.申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符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.綁定共享內(nèi)存shmat

image-20230225230606913

#include "head.h"int main() {//1.申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);//3.將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)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.申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);//3.將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)void *shmemory = NULL;if ((shmemory = shmat(shmid, NULL, 0)) == (void*)-1) {perror("shmat");exit(1);}//4.將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)解除int flag;if ((flag = shmdt(shmemory)) < 0) {perror("shmdt");exit(1);}return 0;
}

5.控制共享內(nèi)存shmctl

image-20230226002223768

#include "head.h"int main() {//1.申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值key_t key;if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}printf("key = 0x%x\n", key);//2.根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符int shmid;if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}printf("shmid = %d\n", shmid);//3.將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)void *shmemory = NULL;if ((shmemory = shmat(shmid, NULL, 0)) == (void*)-1) {perror("shmat");exit(1);}//4.將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)解除int flag;if ((flag = shmdt(shmemory)) < 0) {perror("shmdt");exit(1);}//5.shmctl刪除共享內(nèi)存空間if ((flag = shmctl(shmid, IPC_RMID, NULL)) < 0) {perror("shmctl");exit(1);}return 0;
}

三、親緣進(jìn)程間通信

1.共享內(nèi)存寫入與讀取

#include "head.h"//共享內(nèi)存綜合運(yùn)用
int main() {key_t key;int shmid;pid_t pid;char *shmemory = NULL;//1.開辟一塊共享內(nèi)存空間//(1)申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}//(2)根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}//(3)將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)if ((shmemory = shmat(shmid, NULL, 0)) == (void *)-1) {perror("shmat");exit(1);}//2.創(chuàng)建子進(jìn)程 進(jìn)行運(yùn)算操作if ((pid = fork()) < 0) {perror("fork");exit(1);}if (pid) {//父進(jìn)程寫入while(1) {printf("i am the father : \n");scanf("%[^\n]s", shmemory);//向共享內(nèi)存中寫入getchar();//吞掉回車否則不停循環(huán)sleep(2);}} else {//子進(jìn)程讀出while (1) {sleep(1);if (strlen(shmemory)) printf("i am the child : %s\n", shmemory);//如果共享內(nèi)存空間中有數(shù)據(jù)才進(jìn)行輸出memset(shmemory, 0, 4096);//臨時清空共享存儲空間}}return 0;
}

image-20230228214143422

2.共享內(nèi)存解綁與刪除

#include "head.h"//共享內(nèi)存綜合運(yùn)用
int main() {key_t key;int shmid;pid_t pid;char *shmemory = NULL;//1.開辟一塊共享內(nèi)存空間//(1)申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值if ((key = ftok("1.ftok.c", 123)) < 0) {perror("ftok");exit(1);}//(2)根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符if ((shmid = shmget(key, 4096, IPC_CREAT | 0666)) < 0) {perror("shmget");exit(1);}//(3)將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)if ((shmemory = shmat(shmid, NULL, 0)) == (void *)-1) {perror("shmat");exit(1);}//2.創(chuàng)建子進(jìn)程 利用shmdt實(shí)現(xiàn) 一次讀取一次讀入操作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.刪除開辟的共享內(nèi)存空間//(1)將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)解除int flag;if ((flag = shmdt(shmemory)) < 0) {perror("shmdt");exit(1);}//(2)shmctl刪除共享內(nèi)存空間(父進(jìn)程執(zhí)行)if (pid) {wait(NULL);if ((flag = shmctl(shmid, IPC_RMID, NULL)) < 0) {perror("shmctl");exit(1);}}sleep(5);return 0;
}

image-20230228215903113

3.共享內(nèi)存綜合

  • 利用共享內(nèi)存實(shí)現(xiàn)多進(jìn)程前n項(xiàng)數(shù)求和(利用共享內(nèi)存實(shí)現(xiàn))
#include "head.h"struct data {int now;//中間結(jié)果int sum;//求和結(jié)果
};void doSum(struct data *d, int max, int i) {while (1) {//計(jì)算的過程需要上鎖if (d->now >= max) break;//判斷 計(jì)算結(jié)果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.共享內(nèi)存的創(chuàng)建于綁定key_t key;int shmid;struct data *shmemory = NULL;//2.1申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值if ((key = ftok("5.shm_sum.c", 123)) == -1) {perror("ftok");exit(1);}//2.2根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符if ((shmid = shmget(key, sizeof(struct data), IPC_CREAT | 0600)) < 0) {perror("shmget");exit(1);}//2.3將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)if ((shmemory = (struct data *)shmat(shmid, NULL, 0)) == (struct data *)-1) {perror("shmat");exit(1);}shmemory->now = 0;shmemory->sum = 0;//3.創(chuàng)建ins個子進(jìn)程對文件進(jìn)行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

成功輸出結(jié)果,前100項(xiàng)求和的結(jié)果為5050,但是當(dāng)使用程序求前10000項(xiàng)和時,卻會出現(xiàn)問題如圖結(jié)果為50007661(錯誤結(jié)果)。

image-20230228223444201

出現(xiàn)問題的原因是:執(zhí)行中的進(jìn)程沒有保障,進(jìn)程之間發(fā)生競爭(同一時刻多個進(jìn)程對內(nèi)存進(jìn)行讀寫操作,發(fā)生在多核處理器)

可以利用條件變量實(shí)現(xiàn)線程同步機(jī)制(進(jìn)程同步),從而避免資源搶占競爭。

四、非親緣進(jìn)程間通信

共享內(nèi)存實(shí)現(xiàn)多進(jìn)程計(jì)算,

  1. 單核不考慮同步關(guān)系,可以正常實(shí)現(xiàn)
  2. 多核不考慮同步關(guān)系,無法正常實(shí)現(xiàn)
  3. 需要設(shè)置同步關(guān)系
  4. 利用條件變量實(shí)現(xiàn)進(jìn)程同步

非親緣進(jìn)程之間的通信,

1.通過sleep同步

  • 使用共享內(nèi)存實(shí)現(xiàn)兩個非親緣關(guān)系進(jìn)程(1號進(jìn)程、2號進(jìn)程)進(jìn)行通話
  • 1號進(jìn)程只輸出2號進(jìn)程在共享內(nèi)存中輸入的數(shù)據(jù)
  • 2號進(jìn)程只輸出1號進(jìn)程在共享內(nèi)存中輸入的數(shù)據(jù)
  • 同步(通過sleep實(shí)現(xiàn)同步)
#include "head.h"struct SHM {int flag;//SHM能否讀寫int type;//第幾個進(jìn)程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;//用于臨時存放準(zhǔn)備寫入共享內(nèi)存的數(shù)據(jù)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); 會出現(xiàn)segmentfault呢?*必須使用臨時變量 int type; 來轉(zhuǎn)接數(shù)據(jù)才不會報(bào)錯? */temp->type = type;strcpy(temp->mesg, mesg);//2.共享內(nèi)存的創(chuàng)建與綁定key_t key;int shmid;struct SHM *shmemory = NULL;//2.1申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值if ((key = ftok("1.shm_my.c", 123)) == -1) {perror("ftok");exit(1);}//2.2根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符if ((shmid = shmget(key, sizeof(struct SHM), IPC_CREAT | IPC_EXCL | 0600)) < 0) {if (errno == EEXIST) {//處理重復(fù)創(chuàng)建共享內(nèi)存空間if ((shmid = shmget(key, sizeof(struct SHM), 0600)) < 0) {perror("shmget1");exit(1);}printf("shmemory exist!");} else {perror("shmget2");exit(1);}}//2.3將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)if ((shmemory = (struct SHM *)shmat(shmid, NULL, 0)) == (struct SHM *)-1) {perror("shmat");exit(1);}//3.實(shí)現(xiàn)非親緣進(jìn)程間通信shmemory->flag = 0;//初始狀態(tài)為允許寫入while (1) {if (!shmemory->flag) {printf("<Process%d> : i get shmemory\n", temp->type);sprintf(shmemory->mesg, "<Process%d> : <%s>", temp->type, temp->mesg);//向共享內(nèi)存中寫入內(nèi)容shmemory->flag = 1;sleep(1);} else {printf("%s\n", shmemory->mesg);//從共享內(nèi)存中讀取 并輸出內(nèi)容shmemory->flag = 0;}}return 0;
}

image-20230301103041419

2.通過條件變量同步

思考:如何通過條件變量以及互斥鎖,通過共享內(nèi)存空間實(shí)現(xiàn)多進(jìn)程同步

  • 一個進(jìn)程1號進(jìn)程,作為主要發(fā)送進(jìn)程
  • 多個進(jìn)程,輸出1號進(jìn)程發(fā)送的數(shù)據(jù)
  • 利用條件變量和互斥鎖實(shí)現(xiàn)同步

image-20230301110138124

#include "head.h"struct SHM {int type;//第幾個進(jìn)程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.共享內(nèi)存的創(chuàng)建與綁定key_t key;int shmid;struct SHM *shmemory = NULL;//2.1申請一塊共享內(nèi)存 將projectId與文件名字轉(zhuǎn)換為 共享內(nèi)存鍵值if ((key = ftok("2.shm_cond.c", 123)) == -1) {perror("ftok");exit(1);}//2.2根據(jù)共享內(nèi)存對應(yīng)的key值 和內(nèi)存大小size 得到共享內(nèi)存的標(biāo)識符if ((shmid = shmget(key, sizeof(struct SHM), IPC_CREAT | IPC_EXCL | 0600)) < 0) {if (errno == EEXIST) {//處理重復(fù)創(chuàng)建共享內(nèi)存空間if ((shmid = shmget(key, sizeof(struct SHM), 0600)) < 0) {perror("shmget1");exit(1);}printf("shmemory exist!\n");} else {perror("shmget2");exit(1);}}//2.3將進(jìn)程的動態(tài)內(nèi)存空間和 共享內(nèi)存空間關(guān)聯(lián)if ((shmemory = (struct SHM *)shmat(shmid, NULL, 0)) == (struct SHM *)-1) {perror("shmat");exit(1);}//3.實(shí)現(xiàn)非親緣進(jìn)程間通信if (type == 1) {//讓1號進(jìn)程初始化互斥鎖和信號量 并設(shè)為共享pthread_mutexattr_t mutex;pthread_condattr_t cond;pthread_mutexattr_init(&mutex);pthread_condattr_init(&cond);pthread_mutexattr_setpshared(&mutex, 1);//設(shè)置為共享pthread_condattr_setpshared(&cond, 1);//設(shè)置為共享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號進(jìn)程寫入后通知其他進(jìn)程}} else {while (1) {pthread_mutex_lock(&shmemory->mutex);//一旦有某個進(jìn)程拿到了共享內(nèi)存 則將共享內(nèi)存上鎖pthread_cond_wait(&shmemory->cond, &shmemory->mutex);//共享內(nèi)存上鎖后 等待1號進(jìn)程寫入完成的通知//if (strlen(shmemory->mesg)) printf("<Process%d> : %s\n", type, shmemory->mesg);//將共享內(nèi)存中寫入的數(shù)據(jù)輸出memset(shmemory->mesg, 0, strlen(shmemory->mesg));//清空共享內(nèi)存pthread_mutex_unlock(&shmemory->mutex);}}return 0;
}

image-20230301171032340

http://www.risenshineclean.com/news/65050.html

相關(guān)文章:

  • 動態(tài)網(wǎng)頁技術(shù)seo排名優(yōu)化公司
  • 局域網(wǎng)內(nèi)個人網(wǎng)站建設(shè)軟文大全
  • 太原網(wǎng)站設(shè)計(jì)公司泉州關(guān)鍵詞快速排名
  • 交三百能在網(wǎng)站上找兼職做的地推十大推廣app平臺
  • 坪地網(wǎng)站建設(shè)包括哪些河源新聞最新消息
  • 淘客推廣平臺濟(jì)南網(wǎng)站優(yōu)化培訓(xùn)
  • 藍(lán)色腳手架織夢企業(yè)網(wǎng)站模板網(wǎng)站新站整站排名
  • 網(wǎng)站開發(fā)廣告語大全網(wǎng)絡(luò)營銷師課程
  • wordpress主題圖標(biāo)亂碼武漢seo搜索引擎優(yōu)化
  • 深圳市龍崗區(qū)疫情百度推廣優(yōu)化是什么?
  • 做網(wǎng)上商城網(wǎng)站設(shè)計(jì)靠譜的廣告聯(lián)盟
  • 哈爾濱做網(wǎng)站哈爾濱學(xué)院seovip培訓(xùn)
  • icp備案網(wǎng)站接入信息 ip地址段怎么創(chuàng)建個人網(wǎng)站
  • wordpress commentseo優(yōu)化人員
  • 深圳網(wǎng)站開發(fā)哪家服務(wù)專業(yè)怎么申請網(wǎng)站
  • 網(wǎng)站后臺用什么做優(yōu)化流程
  • 臨沂網(wǎng)站開發(fā)如何優(yōu)化企業(yè)網(wǎng)站
  • 東軟 網(wǎng)站群平臺建設(shè)怎么利用互聯(lián)網(wǎng)推廣
  • 專門做網(wǎng)站代購的盈利路子郴州seo
  • 武漢市有做網(wǎng)站的嗎營業(yè)推廣策劃方案
  • 電商網(wǎng)站有哪些功能模塊bt磁力bt天堂
  • 怎么制作一個app應(yīng)用佛山做seo推廣公司
  • 門戶網(wǎng)站cmssem競價代運(yùn)營
  • 移動網(wǎng)站建設(shè)方面廊坊百度關(guān)鍵詞優(yōu)化
  • 網(wǎng)站開發(fā)怎樣建立后臺數(shù)據(jù)推廣產(chǎn)品的軟文怎么寫
  • 怎么搭建釣魚網(wǎng)站百度指數(shù)第一
  • 門戶網(wǎng)站如何運(yùn)營百度電商推廣
  • 哪個網(wǎng)站做攻略比較好seo 網(wǎng)站優(yōu)化推廣排名教程
  • 新人做網(wǎng)站不懂設(shè)計(jì)版面怎么辦西安seo培訓(xùn)
  • 裝修公司網(wǎng)站dede模板seo網(wǎng)站優(yōu)化專家