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

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

建設(shè)禮品網(wǎng)站的策劃書sem推廣什么意思

建設(shè)禮品網(wǎng)站的策劃書,sem推廣什么意思,網(wǎng)站做收錄,東直門小學(xué)的網(wǎng)站建設(shè)system V一、system V介紹二 、共享內(nèi)存2.1 共享內(nèi)存的原理2.2 共享內(nèi)存接口2.2.1 創(chuàng)建共享內(nèi)存shmget2.2.2 查看IPC資源2.2.3 共享內(nèi)存的控制shmctl2.2.4 共享內(nèi)存的關(guān)聯(lián)shmat2.2.5 共享內(nèi)存的去關(guān)聯(lián)shmdt2.3 進(jìn)程間通信2.4 共享內(nèi)存的特性2.5 共享內(nèi)存的大小三、消息隊(duì)列3.1 …

system V

  • 一、system V介紹
  • 二 、共享內(nèi)存
    • 2.1 共享內(nèi)存的原理
    • 2.2 共享內(nèi)存接口
      • 2.2.1 創(chuàng)建共享內(nèi)存shmget
      • 2.2.2 查看IPC資源
      • 2.2.3 共享內(nèi)存的控制shmctl
      • 2.2.4 共享內(nèi)存的關(guān)聯(lián)shmat
      • 2.2.5 共享內(nèi)存的去關(guān)聯(lián)shmdt
    • 2.3 進(jìn)程間通信
    • 2.4 共享內(nèi)存的特性
    • 2.5 共享內(nèi)存的大小
  • 三、消息隊(duì)列
    • 3.1 消息隊(duì)列的概念
    • 3.2 消息隊(duì)列接口
      • 3.2.1 消息隊(duì)列的獲取msgget
      • 3.2.2 消息隊(duì)列的控制msgctl
      • 3.2.3 消息隊(duì)列發(fā)送數(shù)據(jù)msgsnd
      • 3.2.4 消息隊(duì)列獲取msgrcv
  • 四、信號(hào)量
    • 4.1 信號(hào)量概念
    • 4.2 信號(hào)量的用處
    • 4.3 信號(hào)量的pv操作
    • 4.4 信號(hào)量接口
      • 4.4.1 信號(hào)量申請(qǐng)semget
      • 4.4.2 信號(hào)量控制semctl
      • 4.4.3 信號(hào)量操作semop
  • 五、總結(jié)

一、system V介紹

進(jìn)程間通信除了通過管道,都是基于文件的通信方式,還有一種方式是:SystemV標(biāo)準(zhǔn)的進(jìn)程間通信方式。SystemV是一個(gè)在OS層面專門為進(jìn)程通信設(shè)計(jì)的一個(gè)方案。這些都是由計(jì)算機(jī)科學(xué)家和程序員設(shè)計(jì)的,并且需要給用戶使用。

如果要給用戶用,是以什么方式給用戶使用的呢?在操作系統(tǒng)層面上,SystemV是OS內(nèi)核的一部分,是為OS中多進(jìn)程提供的一種通信方案。但是OS不相信任何用戶,給用戶提供功能的時(shí)候,采用系統(tǒng)調(diào)用。所以System V進(jìn)程間通信,一定會(huì)存在專門用來通信的接口:system call。

因?yàn)樵谠缙谟珊芏嗟姆桨?#xff0c;但是我們需要統(tǒng)一使用一個(gè)方案,所以現(xiàn)在誕生了在統(tǒng)一主機(jī)內(nèi)的進(jìn)程間通信方案:system V方案

system V IPC提供的通信方式有三種: 共享內(nèi)存、消息隊(duì)列、信號(hào)量

二 、共享內(nèi)存

2.1 共享內(nèi)存的原理

前面說過兩個(gè)進(jìn)程要通信就需要看到同一塊資源。

而我們知道進(jìn)程之間具有獨(dú)立性,物理內(nèi)存當(dāng)中代碼和數(shù)據(jù)也互相獨(dú)立。
那么現(xiàn)在我們可以在物理內(nèi)存中創(chuàng)建一個(gè)內(nèi)存塊,讓不同的進(jìn)程都能看到這個(gè)內(nèi)存塊,具體的做法如下:

1?? 通過某種調(diào)用,在內(nèi)存中創(chuàng)建一份內(nèi)存空間。
2?? 通過某種調(diào)用,讓進(jìn)程”掛接“到這份內(nèi)存空間上。(將創(chuàng)建好的內(nèi)存映射進(jìn)進(jìn)程地址空間)
在后面可能不會(huì)共享內(nèi)存了。所以在不用共享內(nèi)存的時(shí)候
3?? 去關(guān)聯(lián)(去掛接)。
4?? 釋放共享內(nèi)存。

對(duì)于共享內(nèi)存的理解:
OS內(nèi)可能存在多個(gè)進(jìn)程同時(shí)使用不同的共享內(nèi)存來進(jìn)行進(jìn)程間通信,既然有多份共享內(nèi)存,那么操作系統(tǒng)就要管理它們,按照前面學(xué)習(xí)的經(jīng)驗(yàn),先描述后組織,描述就是對(duì)共享內(nèi)存的一系列屬性進(jìn)行描述,而后用數(shù)據(jù)結(jié)構(gòu)組織起來,這樣對(duì)共享內(nèi)存的管理變成了對(duì)數(shù)據(jù)結(jié)構(gòu)的操作。

2.2 共享內(nèi)存接口

2.2.1 創(chuàng)建共享內(nèi)存shmget

shmget:用來創(chuàng)建共享內(nèi)存

 #include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);RETURN VALUEOn success, a valid shared memory identifier is returned.  On errir, -1 is returned, and errno is set to indicate the error.

參數(shù)說明:

size:共享內(nèi)存的大小。
shmflag:通常有兩種選項(xiàng):IPC_CREAT、IPC_EXCL。
IPC_CREAT: 共享內(nèi)存如果不存在,則創(chuàng)建,不存在則獲取。
IPC_EXCL: 無法單獨(dú)使用
IPC_CREAT | IPC_EXCL: 如果不存在就創(chuàng)建,如果存在就出錯(cuò)返回(保證共享內(nèi)存是新創(chuàng)建的)。
如果shmflag是0默認(rèn)就是IPC_CREAT。
key:保證看到同一份共享內(nèi)存,能進(jìn)行唯一性標(biāo)識(shí)(就像省份證號(hào)碼一樣,數(shù)字不重要,只用來標(biāo)識(shí)唯一性)。通過ftok函數(shù)轉(zhuǎn)化。
如果創(chuàng)建成功返回共享內(nèi)存的標(biāo)識(shí)符,如果失敗則返回-1。

ftok:用來形成key

#include <sys/types.h>
#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);
RETURN VALUE
On success, the generated key_t value is returned.  
On failure -1 is returned, with errno indicating the error as for the stat(2) system call.

ftok第一個(gè)參數(shù)是自定義路徑名,第二個(gè)參數(shù)是自定義的項(xiàng)目ID。最后唯一的共享內(nèi)存ID就是通過路徑名+項(xiàng)目ID來標(biāo)識(shí)。最后生成的返回值并不重要,只要它能生成一個(gè)值來唯一標(biāo)識(shí)這塊共享內(nèi)存就可以。
只要參數(shù)不變,生成的返回值就不會(huì)變。 這樣就可以讓兩個(gè)進(jìn)程擁有同一個(gè)key,就可以用key找到同一份共享內(nèi)存。

key_t GetKey()
{key_t n = ftok(PATHNAME, PROJ_ID);if(n == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return n;
}int Creatshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | IPC_EXCL | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}int Getshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}

key的理解:
上面也說過了OS會(huì)把內(nèi)存塊管理起來,共享內(nèi)存=物理內(nèi)存塊+共享內(nèi)存的相關(guān)屬性描述共享內(nèi)存時(shí)就有一個(gè)字段struct shm中有key。 一個(gè)進(jìn)程創(chuàng)建內(nèi)存塊后把key值寫進(jìn)相關(guān)屬性中,而另一個(gè)進(jìn)程拿著key值遍歷相關(guān)屬性查找。這樣就完成了兩個(gè)進(jìn)程共享一塊內(nèi)存塊。
我們發(fā)現(xiàn)key和shmid都是標(biāo)識(shí)內(nèi)存塊的:key是在內(nèi)核標(biāo)識(shí)唯一性,而shmid是在用戶層標(biāo)識(shí)唯一性,這樣即使操作系統(tǒng)有什么變化也不會(huì)影響用戶使用,充分的解耦。他們的關(guān)系就類似于fd與inode。

2.2.2 查看IPC資源

共享內(nèi)存的生命周期不是隨著進(jìn)程的,而是隨著OS的,這也是所有system V進(jìn)程間通信的特征。

ipcs -m 查看共享內(nèi)存
在這里插入圖片描述
ipcs -q 查看消息隊(duì)列
ipcs -s 查看信號(hào)量
在這里插入圖片描述

ipcs 三個(gè)一起查看
在這里插入圖片描述
ipcrm -m shmid 刪除共享內(nèi)存
在這里插入圖片描述

2.2.3 共享內(nèi)存的控制shmctl

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

#include <sys/ipc.h>
#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);

它的作用是對(duì)共享內(nèi)存的控制
參數(shù)介紹:
shmid:控制共享內(nèi)存的標(biāo)識(shí)符。
cmd:控制的種類,主要用的是IPC_RMID(立即移除共享內(nèi)存)。
buf:控制共享內(nèi)存的數(shù)據(jù)結(jié)構(gòu),設(shè)置為空即可。
返回值:0表示返回成功,-1表示失敗。

void Delshm(int shmid)
{if(shmctl(shmid, IPC_RMID, nullptr) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}

2.2.4 共享內(nèi)存的關(guān)聯(lián)shmat

#include <sys/types.h>
#include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);

參數(shù)介紹:
shmaddr:可以指定虛擬內(nèi)存,設(shè)置為nullptr即可。
shmflg:讀取權(quán)限,默認(rèn)為0。
返回值:返回共享內(nèi)存的起始地址。

void* Attachshm(int shmid)
{void* mem = shmat(shmid, nullptr, 0);if((long long)mem == -1L)// 64位指針8字節(jié){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return mem;
}

2.2.5 共享內(nèi)存的去關(guān)聯(lián)shmdt

去關(guān)聯(lián)是指把進(jìn)程和共享內(nèi)存之間的映射關(guān)系刪掉(修改頁表),并不是刪除共享內(nèi)存。

#include <sys/types.h>
#include <sys/shm.h>int shmdt(const void *shmaddr);

它的參數(shù)就是在shmat返回的參數(shù)。
成功返回0,失敗返回-1。

void Detachshm(void* start)
{if(shmdt(start) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}

2.3 進(jìn)程間通信

comm.hpp

#ifndef _COMM_HPP_
#define _COMM_HPP_#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <cerrno>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>#define PATHNAME ".."
#define PROJ_ID 12345
#define SIZE 4096key_t GetKey()
{key_t n = ftok(PATHNAME, PROJ_ID);if(n == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return n;
}int Creatshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | IPC_EXCL | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}int Getshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}void Delshm(int shmid)
{if(shmctl(shmid, IPC_RMID, nullptr) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}void* Attachshm(int shmid)
{void* mem = shmat(shmid, nullptr, 0);if((long long)mem == -1L)// 64位指針8字節(jié){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return mem;
}void Detachshm(void* start)
{if(shmdt(start) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}#endif

shm_a.cc

#include "comm.hpp"int main()
{key_t k = GetKey();// 創(chuàng)建共享內(nèi)存int shmid = Creatshm(k);// 掛接char* start = (char*)Attachshm(shmid);//使用while(true){if(strlen(start) > 4){printf("%s\n", start);}if(strlen(start) == 4){break;}sleep(1);}// 去關(guān)聯(lián)Detachshm(start);// 刪除共享內(nèi)存Delshm(shmid);return 0;
}

shm_b.cc

#include "comm.hpp"int main()
{key_t k = GetKey();// 獲取共享內(nèi)存int shmid = Getshm(k);// 掛接char* start = (char*)Attachshm(shmid);// 使用std::string str = "hello shm";int cnt = 0;while(cnt != 8){snprintf(start, SIZE, "%s[%d]", str.c_str(),  cnt);cnt++;sleep(1);}std::string cmd = "stop";snprintf(start, SIZE, "%s", cmd.c_str());// 去關(guān)聯(lián)Detachshm(start);return 0;
}

2.4 共享內(nèi)存的特性

1?? 共享內(nèi)存是所有的進(jìn)程間通信速度最快的。(優(yōu)點(diǎn))
2?? 共享內(nèi)存不提供任何同步或者互斥機(jī)制,不提供不代表不需要,所以需要程序員自行保證數(shù)據(jù)的安全!這也造成了共享內(nèi)存在多進(jìn)程中是不太安全的。(缺點(diǎn))
3?? 共享內(nèi)存的生命周期是隨OS的,而不是隨進(jìn)程的,這是所有System V進(jìn)程間通信的共性。

為什么速度快呢?
管道和共享內(nèi)存:考慮鍵盤輸入,和顯示器輸出,對(duì)于同一份數(shù)據(jù),共享內(nèi)存有幾次數(shù)據(jù)拷貝,管道有幾次數(shù)據(jù)拷貝

管道:在這里插入圖片描述
可以看到寫到管道需要拷貝兩次,而另一個(gè)進(jìn)程讀也需要兩次,所以一共四次。如果考慮到輸入輸出外設(shè),那么就是六次。

共享內(nèi)存:
直接寫入共享內(nèi)存,直接從共享內(nèi)存輸出,所以是兩次??紤]到輸入輸出的話就是四次。

2.5 共享內(nèi)存的大小

這里講的是shget的第二個(gè)參數(shù),一般建議設(shè)置成4096(4KB)的整數(shù)倍,因?yàn)?strong>系統(tǒng)分享內(nèi)存是以4KB為單位,假如我們申請(qǐng)的是4097,那么系統(tǒng)就會(huì)直接向上取整,也就是4096*2,但是我們只能使用其中的4097大小。

三、消息隊(duì)列

3.1 消息隊(duì)列的概念

消息隊(duì)列提供了一個(gè)從一個(gè)進(jìn)程向另外一個(gè)進(jìn)程發(fā)送一塊數(shù)據(jù)的方法,讀端和寫端公用一個(gè)隊(duì)列,每個(gè)數(shù)據(jù)塊就是隊(duì)列的一個(gè)節(jié)點(diǎn),每個(gè)數(shù)據(jù)塊都會(huì)有個(gè)記錄類型的數(shù)據(jù),來判斷該數(shù)據(jù)塊該被哪個(gè)進(jìn)程讀取。

3.2 消息隊(duì)列接口

3.2.1 消息隊(duì)列的獲取msgget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgget(key_t key, int msgflg);

這里的msgflg跟共享內(nèi)存的兩個(gè)參數(shù)一摸一樣(IPC_CREAT、IPC_EXCL)。

返回值:msgget函數(shù)返回的一個(gè)有效的消息隊(duì)列標(biāo)識(shí)符

3.2.2 消息隊(duì)列的控制msgctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgctl(int msqid, int cmd, struct msqid_ds *buf);

參數(shù)說明:
msqid:消息隊(duì)列的標(biāo)識(shí)符。
其他的參數(shù)跟shmctl一樣。

3.2.3 消息隊(duì)列發(fā)送數(shù)據(jù)msgsnd

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

參數(shù)說明:
msqid:消息隊(duì)列的用戶級(jí)標(biāo)識(shí)符。
msgp:表示待發(fā)送的數(shù)據(jù)塊(輸出型參數(shù))。
在這里插入圖片描述

msgsz:表示所發(fā)送數(shù)據(jù)塊的大小
msgflg:表示發(fā)送數(shù)據(jù)塊的方式,一般默認(rèn)為0即可
成功返回0,失敗返回-1

3.2.4 消息隊(duì)列獲取msgrcv

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)

參數(shù)跟上面msgsnd一致。

四、信號(hào)量

4.1 信號(hào)量概念

信號(hào)量本質(zhì)上就是個(gè)計(jì)數(shù)器,它統(tǒng)計(jì)的是公共資源資源還剩多少。

公共資源:可以被多個(gè)進(jìn)程同時(shí)訪問的資源,而如果訪問沒有被保護(hù)的公共資源,就會(huì)導(dǎo)致數(shù)據(jù)不一致問題(一個(gè)進(jìn)程還在寫的時(shí)候另一個(gè)進(jìn)程就開始讀)。所以公共資源需要保護(hù),被保護(hù)起來的資源稱為臨界資源。而訪問這些臨界資源的那部分代碼稱為臨界區(qū)。其他的代碼就稱為非臨界區(qū)。

保護(hù)公共資源:同步和互斥

互斥:當(dāng)有多個(gè)進(jìn)程想要訪問同一份資源的時(shí)候,我們只允許一個(gè)進(jìn)程訪問,當(dāng)這個(gè)進(jìn)程訪問完了,下一個(gè)進(jìn)程才能訪問。

原子性:要么不做,要么做完,只有這兩種狀態(tài)的情況。

既然我們想讓多個(gè)進(jìn)程看到同一個(gè)計(jì)數(shù)器,那么信號(hào)量也是個(gè)公共資源。

4.2 信號(hào)量的用處

舉個(gè)例子,假設(shè)我們要去看電影,而里面的座位只有我們買了票才能擁有,這里的票就是信號(hào)量,我們買了一張后,信號(hào)量就--

所以當(dāng)我們想要某種資源的時(shí)候,我們可以進(jìn)行預(yù)定(買票成功)。
共享資源可以作為一個(gè)整體使用或者劃分成多個(gè)子資源部分。大部分都是整體使用,比如果管道。

如果我們申請(qǐng)成功,相當(dāng)于我們預(yù)定了共享內(nèi)存中的一小部分資源。如果不成功,就不能訪問共享資源,以達(dá)到保護(hù)其他進(jìn)程的目的。

在訪問公共資源前要先申請(qǐng)信號(hào)量,而信號(hào)量本身就是個(gè)公共資源,那么信號(hào)量也帶保護(hù)自己的安全。那么如何保證呢?

4.3 信號(hào)量的pv操作

信號(hào)量操作本質(zhì)上就是計(jì)數(shù)器的++或者--,是原子性的。當(dāng)我們預(yù)定資源的時(shí)候(--)稱為p操作,釋放資源(++)稱為v操作。
如果信號(hào)量的初始值是1就代表了訪問公共資源作為一個(gè)整體來使用,一個(gè)進(jìn)程申請(qǐng)了別的進(jìn)程就不能再申請(qǐng)了,我們把只有兩種狀態(tài)的信號(hào)量稱為二元信號(hào)量。

4.4 信號(hào)量接口

4.4.1 信號(hào)量申請(qǐng)semget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);

參數(shù)介紹:

nsems:表示申請(qǐng)信號(hào)量的個(gè)數(shù)
第一個(gè)和第三個(gè)參數(shù)就跟前面的shmget相同。
返回值:信號(hào)量集創(chuàng)建成功時(shí),semget函數(shù)返回的一個(gè)有效的信號(hào)量集標(biāo)識(shí)符

4.4.2 信號(hào)量控制semctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);

參數(shù)介紹:
semid:信號(hào)量標(biāo)識(shí)符
semnum:信號(hào)量的下標(biāo),默認(rèn)0

4.4.3 信號(hào)量操作semop

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);

參數(shù)介紹:
sembuf:一個(gè)結(jié)構(gòu)體

在這里插入圖片描述
sem_num:信號(hào)量下標(biāo)。
sem_op:1表示++p操作,-1表示--v操作。
sem_flg:選項(xiàng)設(shè)為0即可。

nsops:有多少個(gè)sembuf結(jié)構(gòu)體。

五、總結(jié)

我們可以發(fā)現(xiàn),共享內(nèi)存、消息隊(duì)列、信號(hào)量接口相似度非常高,尤其是獲取與刪除,這些都是system V標(biāo)準(zhǔn)的進(jìn)程間通信。
他們的第一個(gè)成員都是ipc_perm

struct ipc_perm {key_t          __key;    /* Key supplied to shmget(2) */uid_t          uid;      /* Effective UID of owner */gid_t          gid;      /* Effective GID of owner */uid_t          cuid;     /* Effective UID of creator */gid_t          cgid;     /* Effective GID of creator */unsigned short mode;     /* Permissions + SHM_DEST andSHM_LOCKED flags */unsigned short __seq;    /* Sequence number */};

我們可能會(huì)申請(qǐng)共享內(nèi)存、消息隊(duì)列、信號(hào)量的任意一種,那么操作系統(tǒng)如何組織它們呢?

因?yàn)?code>ipc_perm是一樣的,所以可以維護(hù)一個(gè)struct ipc_perm*的指針數(shù)組,存共享內(nèi)存、消息隊(duì)列、信號(hào)量它們的第一個(gè)元素的地址,也就是&ipc_perm。
而我們知道結(jié)構(gòu)體的第一個(gè)成員的地址和結(jié)構(gòu)體對(duì)象的地址在數(shù)字上是相等的

所以當(dāng)我們想使用的時(shí)候直接強(qiáng)轉(zhuǎn)成想用的結(jié)構(gòu)體(共享內(nèi)存、消息隊(duì)列、信號(hào)量)就可以。

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

相關(guān)文章:

  • 限制網(wǎng)站訪問ip臺(tái)州網(wǎng)站建設(shè)方案推廣
  • 繁體中文網(wǎng)站 怎么做推文關(guān)鍵詞生成器
  • b2c商城網(wǎng)站營銷方案百度做網(wǎng)站
  • 寧波網(wǎng)站建設(shè)哪里有平臺(tái)代運(yùn)營是什么意思
  • 珠海做網(wǎng)站哪家專業(yè)正規(guī)的代運(yùn)營公司
  • 西安公司注冊(cè)網(wǎng)站推廣軟件哪個(gè)好
  • 國外免費(fèi)logo設(shè)計(jì)網(wǎng)站百度seo排名優(yōu)化公司推薦
  • 河南自助建站建設(shè)代理seo就是搜索引擎廣告
  • 網(wǎng)站群建設(shè)工作百度廣告聯(lián)盟價(jià)格
  • 漳平網(wǎng)絡(luò)建站公司關(guān)鍵詞推廣是什么意思
  • 企業(yè)對(duì)企業(yè)的網(wǎng)站灰色詞優(yōu)化培訓(xùn)
  • 網(wǎng)站多語言建設(shè)國家免費(fèi)培訓(xùn)網(wǎng)站
  • 如何做網(wǎng)站推廣西安百度推廣優(yōu)化公司
  • 那些網(wǎng)站做網(wǎng)批免費(fèi)網(wǎng)絡(luò)空間搜索引擎
  • 目前熱門的網(wǎng)站建設(shè)語言seo+網(wǎng)站排名
  • 廣州企業(yè)如何建網(wǎng)站免費(fèi)域名注冊(cè)二級(jí)域名
  • 網(wǎng)站建設(shè)優(yōu)化服務(wù)網(wǎng)絡(luò)營銷招聘崗位有哪些
  • 2345網(wǎng)址大全的網(wǎng)址廣州:推動(dòng)優(yōu)化防控措施落
  • 做網(wǎng)站如何通過流量賺錢杭州seo網(wǎng)站優(yōu)化公司
  • 施工程找工程做哪個(gè)網(wǎng)站好營銷型網(wǎng)站建設(shè)怎么做
  • 尋找哈爾濱網(wǎng)站建設(shè)市場營銷試題庫(帶答案)
  • 做宣傳圖冊(cè)在什么網(wǎng)站浙江企業(yè)seo推廣
  • 自己做開獎(jiǎng)網(wǎng)站seo外包方案
  • 阿里云做網(wǎng)站經(jīng)費(fèi)seo優(yōu)化網(wǎng)頁
  • 武漢做網(wǎng)站制作創(chuàng)建網(wǎng)站免費(fèi)注冊(cè)
  • 阿里云搭建自己的網(wǎng)站seo崗位是什么意思
  • smarty做網(wǎng)站百度圖片搜索引擎入口
  • 手機(jī)微網(wǎng)站建設(shè)方案網(wǎng)站怎么添加外鏈
  • 網(wǎng)站定向推送怎么做關(guān)鍵詞排名零芯互聯(lián)排名
  • 深圳個(gè)人外貿(mào)網(wǎng)站建排名優(yōu)化哪家好