国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

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

公司網(wǎng)站seo優(yōu)化的線上營銷推廣方式

公司網(wǎng)站seo優(yōu)化的,線上營銷推廣方式,高密做網(wǎng)站哪家好,浠水做網(wǎng)站的進(jìn)程間通信 1. 進(jìn)程間通信的概念2. 匿名管道pipe3. 命名管道FIFO4. 內(nèi)存映射區(qū) 1. 進(jìn)程間通信的概念 在Linux的環(huán)境下,進(jìn)程地址空間是相互獨(dú)立的,每個(gè)進(jìn)程有著各自不同的用戶地址空間。一個(gè)進(jìn)程不能訪問另一個(gè)進(jìn)程中的內(nèi)容,要進(jìn)行數(shù)據(jù)交換必…

進(jìn)程間通信

  • 1. 進(jìn)程間通信的概念
  • 2. 匿名管道pipe
  • 3. 命名管道FIFO
  • 4. 內(nèi)存映射區(qū)

1. 進(jìn)程間通信的概念

在Linux的環(huán)境下,進(jìn)程地址空間是相互獨(dú)立的,每個(gè)進(jìn)程有著各自不同的用戶地址空間。一個(gè)進(jìn)程不能訪問另一個(gè)進(jìn)程中的內(nèi)容,要進(jìn)行數(shù)據(jù)交換必須要通過內(nèi)核,在內(nèi)核中開辟塊緩沖區(qū),一個(gè)進(jìn)程將數(shù)據(jù)從用戶空間拷貝到內(nèi)核緩沖區(qū)中,另一個(gè)進(jìn)程從內(nèi)核緩沖區(qū)中將數(shù)據(jù)讀走。內(nèi)核提供的這種機(jī)制稱為進(jìn)程間通信(IPC)。

在進(jìn)程間完成數(shù)據(jù)傳輸需要借助操作系統(tǒng)提供的特殊方法,比如文件、管道、FIFO、內(nèi)存映射區(qū)、消息隊(duì)列、信號(hào)、套接字等。如今常用的進(jìn)程間通信主要有管道(最簡單)、信號(hào)(開銷最小)、內(nèi)存映射區(qū)(無血緣關(guān)系)、本地套接字(最穩(wěn)定)。

2. 匿名管道pipe

管道是一種最基本的進(jìn)程間通信機(jī)制,也稱為匿名管道,應(yīng)用于有血緣關(guān)系的進(jìn)程間進(jìn)行通信。管道的本質(zhì)是一塊內(nèi)核緩沖區(qū),內(nèi)部使用的環(huán)形隊(duì)列實(shí)現(xiàn),由兩個(gè)文件描述符進(jìn)行引用,其中一個(gè)表示讀端,另一個(gè)表示寫端。管道的數(shù)據(jù)從管道的寫端流入管道,從讀端流出。當(dāng)兩個(gè)進(jìn)程都死亡的時(shí)候,管道也會(huì)自動(dòng)消失。管道不管讀端還是寫端默認(rèn)都是阻塞的。管道的默認(rèn)緩沖區(qū)大小為4K,可以使用ulimit -a命令獲取大小。

在這里插入圖片描述

管道的數(shù)據(jù)一旦被讀走,便不在管道中存在,不可以反復(fù)讀取。管道的數(shù)據(jù)只能在一個(gè)方向上流動(dòng),如果需要實(shí)現(xiàn)雙向流動(dòng)則需要使用兩個(gè)管道。匿名管道只能在有血緣關(guān)系的進(jìn)程中使用。我們用pipe函數(shù)來創(chuàng)建管道。

在這里插入圖片描述

pipe函數(shù)的原型如下:

       #include <unistd.h>int pipe(int pipefd[2]); // 創(chuàng)建管道

其中pipefd為管道寫端和讀端的文件描述符,其中pipefd[0]為管道讀端的文件描述符,pipefd[1]為管道寫端的文件描述符。當(dāng)函數(shù)調(diào)用成功創(chuàng)建了管道返回0,失敗則返回-1并設(shè)置errno。

在使用匿名管道進(jìn)行通信的時(shí)候,一般是先用pipe函數(shù)創(chuàng)建管道,再使用fork函數(shù)創(chuàng)建子進(jìn)程。這樣父子進(jìn)程就具有了相同的文件描述符,就會(huì)指向同一個(gè)管道。

在管道的通信中,讀寫數(shù)據(jù)也是使用readwrite。管道的示例代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>int main()
{// 創(chuàng)建管道//int pipe(int pipefd[2]);int fd[2];int ret = pipe(fd);if(ret < 0){perror("pipe error");return -1;}// 創(chuàng)建子進(jìn)程pid_t pid = fork();if(pid < 0){perror("fork error");return -1;}else if(pid == 0){// 子進(jìn)程關(guān)閉寫端close(fd[1]);char buf[1024];memset(buf, 0x00, sizeof(buf));sleep(5);read(fd[0], buf, sizeof buf);printf("child: read over, pid = [%d], fpid = [%d], buf = [%s]\n", getpid(), getppid(), buf);}else{// 父進(jìn)程關(guān)閉讀端close(fd[0]);write(fd[1], "helloworld", strlen("helloworld"));printf("father: write over, pid = [%d], fpid = [%d]\n", getpid(), getppid());pid_t wpid = wait(NULL);printf("child [%d] is dead!\n", wpid);}return 0;
}

在shell中我們查詢某一個(gè)進(jìn)程的時(shí)候我們會(huì)使用ps -ef | grep --color=auto bash,這里的|就是管道。我們使用父進(jìn)程進(jìn)程去執(zhí)行ps -ef命令,由于我們需要交給grep去作為輸入,所以在父進(jìn)程中需要將輸出重定向到管道的寫端。子進(jìn)程執(zhí)行grep的時(shí)候會(huì)從輸入進(jìn)行讀取內(nèi)容,因此我們需要將輸入重定向到管道讀端。重定向的時(shí)候需要使用dup2函數(shù),需要執(zhí)行命令則需要使用execlexeclp函數(shù),示例程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>int main()
{// 創(chuàng)建管道int pipefd[2];int ret = pipe(pipefd);if(ret < 0){// 創(chuàng)建失敗perror("pipe error");return -1;}// 創(chuàng)建子進(jìn)程pid_t pid = fork();if(pid < 0){// 創(chuàng)建失敗perror("fork error");return -1;}else if(pid == 0){// 子進(jìn)程關(guān)閉寫端close(pipefd[1]);// 將標(biāo)準(zhǔn)輸入重定向到管道讀端dup2(pipefd[0], STDIN_FILENO);execlp("grep", "grep", "--color=auto", "bash", NULL);perror("execlp error");}else {// 父進(jìn)程關(guān)閉讀端close(pipefd[0]);// 將標(biāo)準(zhǔn)輸出重定向到管道寫端dup2(pipefd[1], STDOUT_FILENO);execlp("ps", "ps", "-ef", NULL);perror("execlp error");}return 0;
}

當(dāng)管道有數(shù)據(jù)的時(shí)候,read可以正常讀,并返回讀出來的字節(jié)數(shù);當(dāng)管道沒有數(shù)據(jù)的時(shí)候,若寫端全部關(guān)閉,則read函數(shù)解出阻塞狀態(tài),返回0,相當(dāng)于讀文件讀到了尾部。若寫端沒有關(guān)閉,則read阻塞。

若讀端全部關(guān)閉,進(jìn)行寫操作的時(shí)候則管道會(huì)破裂,進(jìn)程終止,內(nèi)核會(huì)給當(dāng)前進(jìn)程發(fā)送SIGPIPE信號(hào)。若讀端沒有完全關(guān)閉,緩沖區(qū)寫滿了則write會(huì)阻塞,緩沖區(qū)沒有滿則可以繼續(xù)write。

管道默認(rèn)兩端都是阻塞的,若要設(shè)置為非阻塞,則可以使用前面提過的fcntl函數(shù)。首先使用F_GETFL獲取flags,然后在添加O_NONBLOCK使用F_SETFL設(shè)置即可。當(dāng)讀端設(shè)置為非阻塞狀態(tài)的時(shí)候,會(huì)有以下四種情況:

  • 寫端沒有關(guān)閉,管道中沒有數(shù)據(jù)可讀,則read返回-1。
  • 寫端沒有關(guān)閉,管道中有數(shù)據(jù)可讀,則read返回實(shí)際讀到的字節(jié)數(shù)。
  • 寫端已經(jīng)關(guān)閉,管道中有數(shù)據(jù)可讀,則read返回實(shí)際讀到的字節(jié)數(shù)。
  • 寫端已經(jīng)關(guān)閉,管道中沒有數(shù)據(jù)可讀,則read返回0。

設(shè)置的流程為:

int flags = fcntl(fd[0], F_GETFL, 0);
flags = flags | O_NONBLOCK;
fcntl(fd[0], F_SETFL, flags);

除了前面使用的ulimit -a可以查看到管道緩沖區(qū)的大小之外,也可以使用fpathconf函數(shù),該函數(shù)的原型為:

       #include <unistd.h>long fpathconf(int fd, int name); 

這個(gè)函數(shù)會(huì)根據(jù)name的參數(shù)設(shè)置返回文件描述符fd對(duì)應(yīng)文件的配置內(nèi)容。比如獲取管道緩沖區(qū)則需要把name設(shè)置為_PC_PIPE_BUF。如下面查看管道的緩沖區(qū)大小。

printf("pipe size = [%ld]\n", fpathconf(fd[0], _PC_PIPE_BUF));
printf("pipe size = [%ld]\n", fpathconf(fd[1], _PC_PIPE_BUF));

更多的name參數(shù)設(shè)置可以使用man fpathconf查詢幫助文檔。

3. 命名管道FIFO

使用pipe管道只能實(shí)現(xiàn)有血緣關(guān)系的兩個(gè)進(jìn)程間的通信,那么對(duì)于兩個(gè)沒有血緣關(guān)系的進(jìn)程又應(yīng)該怎么實(shí)現(xiàn)呢?則需要這一節(jié)的命名管道FIFO。

FIFO是Linux上基于文件類型的一種通信方式,文件類型為p,但是FIFO在磁盤上并沒有數(shù)據(jù)塊,文件大小為0,僅僅用于標(biāo)識(shí)內(nèi)核中的一條通道。進(jìn)程可以通過read或者write函數(shù)去對(duì)這一條通道進(jìn)行操作,也就是內(nèi)核緩沖區(qū),這樣就實(shí)現(xiàn)了進(jìn)程間的通信。

要使用命名管道,就得先創(chuàng)建命名管道文件,創(chuàng)建管道文件使用mkfifo函數(shù),該函數(shù)的原型為:

       #include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);

其中參數(shù)第一個(gè)pathname表示管道的路徑名,mode表示權(quán)限,使用一個(gè)三位八進(jìn)制數(shù)表示。創(chuàng)建成功函數(shù)返回0,創(chuàng)建失敗則函數(shù)返回-1并設(shè)置errno。

FIFO嚴(yán)格遵守先進(jìn)先出的規(guī)則,也就是對(duì)于管道的讀總是從管道的開始處返回?cái)?shù)據(jù),而對(duì)于管道的寫則是添加到末尾。因此命名管道不支持使用lseek等對(duì)文件定位的操作。

使用FIFO完成進(jìn)程間通信的示意圖如下:

在這里插入圖片描述

既然是兩個(gè)進(jìn)程,也就是說兩個(gè)進(jìn)程中的程序都需要打開管道,也就是需要找到文件。若寫進(jìn)程沒有打開就去使用讀進(jìn)程,則可能因?yàn)楣艿赖奈募淮嬖诙鴪?bào)錯(cuò)。因此我們?cè)谑褂霉艿阑蛘邉?chuàng)建管道之前要先判斷文件是否存在。這個(gè)可以使用access函數(shù)實(shí)現(xiàn),該函數(shù)的原型為:

       #include <unistd.h>int access(const char *pathname, int mode);

該函數(shù)的第一個(gè)參數(shù)pathname是文件的路徑,第二個(gè)參數(shù)mode表示要測(cè)試的模式,有四個(gè)參數(shù)可以傳,分別為:

  • F_OK: 文件存在
  • R_OK:有讀權(quán)限
  • W_OK:有寫權(quán)限
  • X_OK:有執(zhí)行權(quán)限

當(dāng)有對(duì)應(yīng)的權(quán)限或者文件存在的時(shí)候,該函數(shù)的返回值為0,若沒有對(duì)應(yīng)權(quán)限或者文件不存在則該函數(shù)返回-1。

接下來我們實(shí)現(xiàn)兩個(gè)無血緣關(guān)系之間的進(jìn)程間通信。代碼如下:

fifo_write.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>// FIFO 寫進(jìn)程
int main()
{// 創(chuàng)建FIFO文件// int access(const char *pathname, int mode);int ret = access("./myfifo", F_OK);if(ret < 0){// int mkfifo(const char *pathname, mode_t mode);ret = mkfifo("./myfifo", 0777);if(ret < 0){perror("mkfifo error");return -1;}}// 打開FIFOint fd = open("./myfifo", O_RDWR);if(fd < 0){perror("open error");return -1;}// 傳輸數(shù)據(jù)char buf[1024] = "hello world";write(fd, buf, strlen(buf));sleep(1);// 關(guān)閉FIFOclose(fd);return 0;
}

fifo_read.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>// FIFO 讀進(jìn)程端
int main()
{// 判斷創(chuàng)建FIFOint ret = access("./myfifo", F_OK);if(ret < 0){int ret = mkfifo("./myfifo", 0777);if(ret < 0){perror("mkfifo error");return -1;}}// 打開FIFOint fd = open("./myfifo", O_RDWR);if(fd < 0){perror("open error");return -1;}// 接收數(shù)據(jù)char buf[1024];memset(buf, 0x00, sizeof buf);read(fd, buf, sizeof buf);printf("%s\n", buf);// 關(guān)閉FIFOclose(fd);return 0;
}

在上述代碼中,只要運(yùn)行,不管是讀進(jìn)程還是寫進(jìn)程先運(yùn)行,只要寫進(jìn)程沒有往管道中寫數(shù)據(jù),讀進(jìn)程都會(huì)阻塞在read處。直到寫進(jìn)程調(diào)用write函數(shù)往管道中寫數(shù)據(jù)之后讀進(jìn)程才會(huì)讀出來管道中的數(shù)據(jù)輸出。

4. 內(nèi)存映射區(qū)

內(nèi)存映射區(qū)是將一個(gè)磁盤文件與內(nèi)存空間的一個(gè)緩沖區(qū)向映射。當(dāng)我們?cè)诰彌_區(qū)中讀取數(shù)據(jù)的時(shí)候,就相當(dāng)于在文件中讀取相應(yīng)的字節(jié)。若我們向緩沖區(qū)中寫數(shù)據(jù),則會(huì)把數(shù)據(jù)寫入對(duì)應(yīng)的文件之中。這樣就可以在不使用read函數(shù)和write函數(shù)啊的情況下使用指針完成IO操作。

在這里插入圖片描述

映射這個(gè)過程可以使用mmap函數(shù)實(shí)現(xiàn)。解除映射可以使用munmap實(shí)現(xiàn)。函數(shù)的原型以及參數(shù)如下:

       #include <sys/mman.h>// 函數(shù)作用: 建立存儲(chǔ)映射區(qū)// 返回值: 成功:返回創(chuàng)建的映射區(qū)首地址//		  失敗: 返回MAP_FAILED宏, 實(shí)際上就是(void *)-1// 參數(shù): addr: 指定映射的起始地址,通常設(shè)為NULL,由系統(tǒng)指定//      length: 映射到內(nèi)存的文件長度//       prot: 映射區(qū)的保護(hù)方式,最常用的有//                PROT_READ   				讀//                PROT_WRITE  				寫//                PROT_READ | PORT_WRITE    讀寫//       flags: 映射區(qū)的特性,可以設(shè)置以下//                MAP_SHARED   寫入映射區(qū)的數(shù)據(jù)會(huì)寫回文件,且允許//							   其它映射改文件的進(jìn)程共享。//                MAP_PRIVATE  對(duì)映射區(qū)的寫入操作會(huì)產(chǎn)生一個(gè)映射區(qū)的復(fù)//  						 	制,對(duì)此區(qū)域所做的修改不會(huì)寫回原文件。//                MAP_ANONYMOUS  匿名映射區(qū),需要結(jié)合MAP_SHARED使用。// 	      fd: 代表要映射的文件,由open函數(shù)返回的文件描述符//        offset: 以文件開始出的偏移量,必須是4K的整數(shù)倍,通常為0,表示//                從文件頭開始映射void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);// 函數(shù)作用: 釋放由mmap函數(shù)建立的存儲(chǔ)映射區(qū)// 返回值: 成功返回0,失敗返回-1并設(shè)置errno// 參數(shù): addr: 調(diào)用mmap函數(shù)成功返回的映射區(qū)首地址//  	 length: 映射區(qū)的大小int munmap(void *addr, size_t length);

需要注意到的是,mmap函數(shù)不能開辟長度為0的存儲(chǔ)映射區(qū)。在使用mmap函數(shù)創(chuàng)建映射區(qū)的過程中,隱含著一次對(duì)映射文件的讀操作,將文件讀取到映射區(qū)。當(dāng)我們將flags設(shè)置為MAP_SHARED的時(shí)候,要求映射區(qū)的權(quán)限應(yīng)該小于或者等于文件打開的權(quán)限,這是出于對(duì)映射區(qū)的保護(hù)。而對(duì)于MAP_PRIVATE,則是沒有這個(gè)必要,因?yàn)?code>mmap中的權(quán)限是對(duì)內(nèi)存的限制。

在映射區(qū)建立之后,映射區(qū)的釋放是與文件的關(guān)閉無關(guān)的,所以在映射區(qū)建立之后就可以關(guān)閉文件。在創(chuàng)建映射區(qū)的時(shí)候,使用mmap函數(shù)常常會(huì)出現(xiàn)總線錯(cuò)誤,通常是因?yàn)楣蚕砦募鎯?chǔ)空間大小引起的。所以創(chuàng)建映射區(qū)的時(shí)候出錯(cuò)的概率比較高,因此一定要檢查函數(shù)的返回值,確保映射區(qū)建立成功了再進(jìn)行后續(xù)的操作。使用munmap函數(shù)的時(shí)候,傳入的地址一定要是mmap函數(shù)的返回值,一定不要改變指針的指向。其中函數(shù)的參數(shù)中offset也是需要注意的,不能隨便指定,必須要是4K的整數(shù)倍才行。

下面給出一個(gè)關(guān)于關(guān)于有血緣關(guān)系的進(jìn)程間的通信示例。

//使用mmap完成有血緣關(guān)系進(jìn)程間的通信
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>int main()
{//使用mmap函數(shù)建立共享映射區(qū)//void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);int fd = open("test.log", O_RDWR);if(fd < 0){perror("open error");return -1;}int len = lseek(fd, 0, SEEK_END);void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if(addr == MAP_FAILED){perror("mmap error");return -1;}close(fd);//創(chuàng)建子進(jìn)程pid_t pid = fork();if(pid < 0){perror("fork error");return -1;}else if(pid == 0){//子進(jìn)程sleep(2);char *p = (char *)addr;printf("[%s]\n", p);}else{//父進(jìn)程memcpy(addr, "hello world", strlen("hello world"));wait(NULL);}return 0;
}

共享存儲(chǔ)映射區(qū)也可以用于沒有血緣關(guān)系的兩個(gè)進(jìn)程。

寫進(jìn)程

// 使用mmap完成沒有血緣關(guān)系的進(jìn)程間的通信
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>// 寫進(jìn)程
int main()
{// 使用mmap函數(shù)建立共享映射區(qū)int fd = open("test.log", O_RDWR);if(fd < 0){perror("open error");return -1;}int len = lseek(fd, 0, SEEK_END);// 建立共享映射區(qū)void *addr = mmap(NULL, len, PROT_WRITE, MAP_SHARED, fd, 0);if(addr == MAP_FAILED){perror("mmap error");return -1;}close(fd);memcpy(addr, "Good morning", strlen("Good morning"));return 0;
}

讀進(jìn)程

// 使用mmap完成沒有血緣關(guān)系的兩個(gè)進(jìn)程間的通信
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>// 讀進(jìn)程端
int main()
{// 使用mmap函數(shù)建立共享映射區(qū)int fd = open("test.log", O_RDONLY);if(fd < 0){perror("open error");return -1;}int len = lseek(fd, 0, SEEK_END);// 建立共享映射區(qū)void *addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);if(addr == MAP_FAILED){perror("mmap error");return -1;}char *p = (char *)addr;printf("[%s]\n", p);return 0;
}

上面的共享存儲(chǔ)映射區(qū)都是有名字的,我們也可以創(chuàng)建匿名的共享存儲(chǔ)映射區(qū)。匿名映射區(qū)是不需要使用文件去創(chuàng)建的,因此沒有血緣關(guān)系的兩個(gè)進(jìn)程不能使用匿名映射區(qū)通信。在使用匿名共享映射區(qū)的時(shí)候,文件的描述符一般傳為-1。關(guān)于匿名共享映射區(qū)的示例代碼如下:

// 建立匿名共享映射區(qū)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <fcntl.h>int main()
{void *addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);if(addr == MAP_FAILED){perror("mmap error");return -1;}pid_t pid = fork();if(pid < 0){perror("fork error");return -1;}else if(pid == 0){sleep(2);char *p = (char *)addr;printf("[%s]\n", p);}else{memset(addr, 0x00, 4096);memcpy(addr, "hello world", strlen("hello world"));wait(NULL);}return 0;
}

后續(xù)博客關(guān)于函數(shù)原型以及作用均以注釋的形式寫在代碼中以便直觀

http://m.aloenet.com.cn/news/33585.html

相關(guān)文章:

  • 騰訊云 wordpress教程視頻seo外鏈推廣
  • wordpress+技術(shù)類模板網(wǎng)站seo優(yōu)化有哪些方面
  • 在什么網(wǎng)站可以接活做梅州網(wǎng)絡(luò)推廣
  • 布料市場做哪個(gè)網(wǎng)站好代寫軟文
  • 動(dòng)漫網(wǎng)站設(shè)計(jì)方案華為手機(jī)軟文范文300
  • 網(wǎng)站群如何做網(wǎng)站seo快速優(yōu)化軟件
  • 單位網(wǎng)站中文域名到期續(xù)費(fèi)seo的培訓(xùn)班
  • 梧州網(wǎng)站建設(shè)設(shè)計(jì)百度服務(wù)電話在線人工
  • 做網(wǎng)站用什么字體字號(hào)seo技術(shù)優(yōu)化服務(wù)
  • wordpress換域名了 登陸不了五年級(jí)下冊(cè)數(shù)學(xué)優(yōu)化設(shè)計(jì)答案
  • 域名 備案 沒有網(wǎng)站嗎網(wǎng)絡(luò)營銷的有哪些特點(diǎn)
  • 怎么自己做網(wǎng)站嚇別人佛山seo聯(lián)系方式
  • 剛注冊(cè)公司怎么做網(wǎng)站seo案例分析100例
  • 云推廣關(guān)鍵詞優(yōu)化是怎么弄的
  • 公司網(wǎng)站的管理和維護(hù)uc瀏覽網(wǎng)頁版進(jìn)入
  • 制作網(wǎng)站步驟新媒體營銷案例ppt
  • 網(wǎng)頁設(shè)計(jì)的動(dòng)態(tài)網(wǎng)站怎么做騰訊企點(diǎn)官網(wǎng)下載
  • 前端和網(wǎng)站建設(shè)的區(qū)別友情手機(jī)站
  • 宜興建設(shè)局網(wǎng)站長沙seo行者seo09
  • wordpress采集處理樣式廣東優(yōu)化疫情防控措施
  • 做網(wǎng)站3個(gè)月搜索引擎營銷流程是什么?
  • 簡約風(fēng)格網(wǎng)站代哥seo
  • 男和女做暖暖網(wǎng)站網(wǎng)絡(luò)銷售怎么找客戶
  • 做網(wǎng)站練手優(yōu)化大師電腦版
  • seo黑帽技術(shù)工具陜西seo顧問服務(wù)
  • 真人做爰網(wǎng)站怎么提交網(wǎng)址讓百度收錄
  • 做網(wǎng)站常用代碼向右浮動(dòng)怎么寫凡科網(wǎng)怎么建網(wǎng)站
  • 有了 ftp服務(wù)器密碼 怎么改網(wǎng)站給我免費(fèi)播放片高清在線觀看
  • 網(wǎng)站域名代辦百度搜索鏈接
  • 國外做的好的醫(yī)療網(wǎng)站網(wǎng)站域名服務(wù)器查詢