intpipe(intfd[2]);//標(biāo)準(zhǔn)I/O庫提供了兩個函數(shù),實現(xiàn)的操作是創(chuàng)建一個管道fork一個子進程關(guān)閉未//使用的管道端,執(zhí)行一個shell運行命令,然后等待命令終止//type類似fopen函數(shù),有"r","w"或者"rw"等#includeFILE*popen(constchar*cmdstring,constchar*type);intpclose(FILE*fp)" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

UNIX環(huán)境高級編程 進程間通訊

系統(tǒng) 1610 0

?

?

相關(guān)函數(shù)列表

      //管道
#include <unistd.h>
int pipe(int fd[2]);

//標(biāo)準(zhǔn)I/O庫提供了兩個函數(shù),實現(xiàn)的操作是創(chuàng)建一個管道fork一個子進程關(guān)閉未
//使用的管道端,執(zhí)行一個shell運行命令,然后等待命令終止
//type類似fopen函數(shù),有"r","w"或者"rw"等
#include <stdio.h>
FILE *popen(const char *cmdstring, const char *type);
int pclose(FILE *fp);


//FIFO有時也被稱為命名管道,未命名的管道只能在兩個相關(guān)進程之間使用,而且這兩個相關(guān)的進程
//還要有一個共同的創(chuàng)建了它們的祖先進程,但FIFO不相關(guān)的進程也能交換數(shù)據(jù)
#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode);
int mkfifoat(int fd, const char *path, mode_t mode);


//下面函數(shù)提供的唯一服務(wù)就是由一個路徑名和項目ID產(chǎn)生一個鍵
#include <sys/ipc.h>
key_t ftok(const char *path, int id);

//XSI IPC為每一個IPC結(jié)構(gòu)關(guān)聯(lián)了一個ipc_perm結(jié)構(gòu),該結(jié)構(gòu)規(guī)定了權(quán)限和所有者,至少包含下面成員
struct ipc_perm {
    uid_t  uid;   //用戶有效ID
    gid_t  gid;   //用戶有效組ID
    uid_t  cuid;  //創(chuàng)建有效用戶ID
    gid_t  cgid;  //創(chuàng)建有效組ID
    mode_t mode   //訪問模式
};  



//消息隊列
//每個隊列都有一個msqid_ds結(jié)構(gòu)與其相關(guān)聯(lián)
struct msqid_ds {
    struct ipc_perm  msg_perm;   //權(quán)限所有者結(jié)構(gòu)
    msgqnum_t        msg_qnum;   //隊列中有多少消息
    msglen_t         msg_qbytes; //隊列的最大字節(jié)數(shù)
    pid_t            msg_lspid;  //mgsend()的 pid
    pid_t            msg_lrpid;  //msgrcv()的 pid
    time_t           msg_stime;  //last msgsend() time
    time_t           msg_rtime;  //last-msgrcv()  time
    time_t           msg_ctime;  //last-change time
};

//打開一個現(xiàn)有的消息隊列或創(chuàng)建一個新隊列
#include <sys/msg.h>
int msgget(key_t key, int flag);

//操作隊列,cmd參數(shù)指定對msqid指定的隊列要執(zhí)行的命令
//IPC_STAT   取此隊列的msqid_ds結(jié)構(gòu),并將它存放在buf指向的結(jié)構(gòu)中
//IPC_SET    將字段msg_perm.uid, msg_perm.gid, msg_perm.mode和 msg_qbytes從buf指向的結(jié)構(gòu)
//           復(fù)制到與這個隊列相關(guān)的msqid_ds結(jié)構(gòu)中,此命令只能由下列兩種進程執(zhí)行:1)一種是其
//           有效用戶ID等于msg_perm.cuid或msg_perm.uid, 2)是一種具有超級用戶特權(quán)的進程,只
//           有超級用戶才能增加msg_qbytes的值
//IPC_RMID   從系統(tǒng)中山川村該消息隊列以及仍在該隊列中的所有數(shù)據(jù)。這種數(shù)據(jù)立即生效。仍在使用
//           這一消息隊列的其他進程再他們下一次試圖對此隊列進行操作時,將得到EIDRM錯誤。此
//           命令只能由下列兩種進程執(zhí)行: 1)一種是有效用戶ID等于msg_perm.cuid或msg_perm.uid
//           2)另一種是具有超級用戶特權(quán)的進程
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_id *buf);

//調(diào)用下面函數(shù)將數(shù)據(jù)放到消息隊列中
//flag參數(shù)的值可以指定為IPC_NOWAIT類似于文件I/O的非阻塞I/O標(biāo)志,
#include <sys/msg.h>
int msgsend(int msqid, const void *ptr, size_t nbytes, int flag);
//prt參數(shù)指向一個長整型。它包含了正的整型消息類型,其后緊接著的是消息數(shù)據(jù)
struct mymesg {
    long mtype;
    char mtext[512];
};

//從隊列中取消息
//和msgsend一樣,ptr參數(shù)指向一個長整型數(shù),其后是存儲實際消息數(shù)據(jù)的緩沖區(qū),nbytes指定數(shù)據(jù)
//緩沖區(qū)的長度,若flag中設(shè)置了MSG_NOERROR,則消息會截斷,參數(shù)type可以指定想要哪一種消息
//type==0  返回隊列中的第一個消息
//type>0   返回隊列中消息類型為type的第一個消息
//type<0   返回隊列中消息類型值小于等于type絕對值的消息
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);


//消息隊列
//每個隊列都有一個msqid_ds結(jié)構(gòu)與其相關(guān)聯(lián)
struct msqid_ds {
    struct ipc_perm   msg_perm;
    msgqunm_t         msg_qnum;
    msglen_t          msg_qbytes;
    pid_t             msg_lspid;   //pid of last msgsend()
    pid_t             msg_lrpid;   //pid of last msgrcv()
    time_t            msg_stime;   //last-msgsend() time
    time_t            msg_rtime;   //last-msgrcv()  time
    time_t            msg_ctime;   //last-change time
};


//信號量
//每個信號量由一個無名結(jié)構(gòu)表示,它至少包含下列成員
struct {
    unsigned short semval;
    pid_t          sempid;
    unsigned short semncnt;
    unsigned short semzcnt;
};

//獲得一個信號量ID
#include <sys/sem.h>
int semget(key_t key, int nsems, int flag);

//用于操作信號量的函數(shù),其中cmd參數(shù)是以下10種命令的一種:
//IPC_STAT    對此集合取semid_ds結(jié)構(gòu),并存儲在由arg.buf指向的結(jié)構(gòu)中
//IPC_SET     按arg.buf指向的結(jié)構(gòu)中的值設(shè)置與集合相關(guān)的結(jié)構(gòu)中的sem_perm.uid等值
//IPC_RMID    從系統(tǒng)中刪除該信號量集合
//GETVAL      返回成員semnum的semval值
//SETVAL      設(shè)置成員semnum的semval值
//GETPID      返回成員semnum的sempid值
//GETNCNT     返回成員semnum的semncnt值
//GETALL      取該集合中所有的信號量值
//SETALL      將該集合中所有的信號量都設(shè)置成arg.array指向的數(shù)組中的值
#include <sys/sem.h>
int semctl(int semid, int semunm, int cmd, ...);

//自動執(zhí)行信號量集合上的從操作數(shù)組
#include <sys/sem.h>
int semop(int semid, struct sembuf semoparray[], size_t nops);
//參數(shù)semoparray是一個指針,它指向一個由sembuf結(jié)構(gòu)表示的信號量操作數(shù)組
struct sembuf {
    unsigned short   sem_num;
    short            sem_op;
    short            sem_flag;
};


//共享內(nèi)存
//內(nèi)核為每個共享內(nèi)存儲段維護者一個結(jié)構(gòu),該結(jié)構(gòu)至少要為每個共享存儲段包含以下成員
struct shmid_ds {
    struct ipc_perm   shm_perm;
    size_t            shm_segsz;
    pid_t             shm_lpid;
    pid_t             shm_cpid;
    shmatt_t          shm_nattch;
    time_t            shm_atime;
    time_t            shm_dtime;
    time_t            shm_ctime;
};


//獲得一個共享存儲的標(biāo)識符
#include <sys/shm.h>
int shmget(key_t key, size_t size, int flag);

//對共享內(nèi)存執(zhí)行多種操作
//參數(shù)cmd指定下列5種命令中的一種,使其在shmid指定的段上執(zhí)行
//IPC_STAT    取此段的shmid_ds結(jié)構(gòu),并將它存儲在由buf指向的結(jié)構(gòu)中
//IPC_SET     按buf指向的結(jié)構(gòu)中的值設(shè)置與此共享存儲段相關(guān)的shmid_ds結(jié)構(gòu)中下一些字段
//IPC_RMID    從系統(tǒng)中刪除該共享存儲段
//SHM_LOCK    在內(nèi)存中對共享存儲段加鎖,只能由超級用戶執(zhí)行
//SHM_UNLOCK  解鎖共享存儲段,只能由超級用戶執(zhí)行
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

//一旦創(chuàng)建了一個共享存儲段,進程就看以調(diào)用shmat將其連接到它的地址空間中
//共享存儲段連接到調(diào)用進程的哪個地址上與addr參數(shù)以及flag中是否指定SHM_RND位有關(guān)
//1.如果addr為0,則此段連接到由內(nèi)核選擇的第一個可用地址上,這是推薦的方式
//2.如果addr非0,并且沒有指定SHM_RND,則此段連接到addr所指定的地址上
//3.如果addr非0,并且指定了SHM_RND,則此段連接到(addr-(addr mod SHMLBA))所表示的地址上,
//  SHM_RND命令的意思是取整,SHMLBA的意思是 低邊界地址倍數(shù)
//如果flag中指定了SHM_RDONLY位,則以只讀方式連接此段,否則以讀寫方式連接此段
#include <sys/shm.h>
void *shmat(int shmid, const void *addr, int flag);

//共享存儲段的操作已經(jīng)結(jié)束時,調(diào)用下面函數(shù)與該段分離,但這并不從系統(tǒng)中刪除其標(biāo)識符以及相關(guān)
//的數(shù)據(jù)結(jié)構(gòu),知道某個進程帶IPC_RMID命令的調(diào)用shmctl特地的刪除它為止
#include <sys/shm.h>
int shmdt(const void *addr);


//POSIX信號量
//使用下面函數(shù)來創(chuàng)建一個新的命名信號量或者使用一個現(xiàn)有信號量
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag, .../* mode_t mode, unsigned int value */);

//下面函數(shù)用來釋放任何信號量相關(guān)的資源
#include <semaphore.h>
int sem_close(sem_t *sem);

//下面函數(shù)用來銷毀一個命名信號量
#include <semaphore.h>
int sem_unlink(const char *name);

//使用下面函數(shù)用來實現(xiàn)信號量的減1操作,try函數(shù)會避免阻塞
#include <semaphore.h>
#include <time.h>
int sem_trywait(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict tsprt);

//使用下面函數(shù)使信號量值增1,這和解鎖一個二進制信號量或者釋放一個計數(shù)信號量相關(guān)的資源過程
//是類似的
#include <semaphore.h>
int sem_pos(sem_t *sem);

//創(chuàng)建一個未命名的信號量
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);

//對未命名信號量的使用已經(jīng)完成時,可以調(diào)用下面函數(shù)丟棄它
#include <semaphore.h>
int sem_destroy(sem_t *sem);

//調(diào)用下面函數(shù)來檢索信號量值
#include <semaphore.h>
int sem_getvalue(sem_t *restrict sem, int *restrict valp);


    

?

?

進程間通訊(Inter Process Communication IPC)

UNIX系統(tǒng)IPC包括半雙工管道,全雙工管道,F(xiàn)IFO,XSI消息隊列,XSI信號量,XSI共享存儲,套接字

?

?

管道

?

管道是UNIX系統(tǒng)IPC的最古老形式,所有UNIX系統(tǒng)都提供此種通訊機制,管道有

下面兩種限制

1)歷史上他們是半雙工的(即數(shù)據(jù)只能在一個方向上流動),限制某些系統(tǒng)提供全

? ?雙工的管道,但是為了最佳的可移植性我們決不預(yù)先假設(shè)系統(tǒng)支持全雙工管道

2)管道只能在具有公共祖先的兩個進程之間使用,通常一個管道由一個進程創(chuàng)建,

? 在進程調(diào)用fork之后,這個管道就能在父進程和子進程之間使用了

? FOFO沒有第二種局限性,UNIX域套接字沒有這兩種局限性

?

經(jīng)由參fd返回兩個文件描述符,fd[0]為讀而打開,fd[1]為寫而打開。 ?fd[1]的輸出是fd[0]

對于一個從子進程到父進程的管道,父進程關(guān)閉fd[1],子進程關(guān)閉fd[0]

?

?

FIFO(命名管道)

當(dāng)open一個FIFO時,非阻塞標(biāo)志(O_NONBLOCK)會產(chǎn)生下列影響

1)在一般情況下(沒有指定O_NONBLOCK),只讀open要阻塞到某個其他進程為寫而打開這個FIFO為止,

? ?類似的,只寫open要阻塞到某個其他進程為讀而打開它為止

2)如果指定了O_NONBLOCK,則只讀open立即返回。但是如果沒有進程為讀而打開一個FIFO,那么只寫

? ?open將返回-1,并將errno設(shè)置為ENXIO

FIFO有以下兩種用途

1)shell命令使用FIFO將數(shù)據(jù)從一條管道傳送到另一條時,無需創(chuàng)建中間臨時文件

2)客戶進程--服務(wù)器進程應(yīng)用程序中,F(xiàn)IFO用作匯聚點,在客戶進程和服務(wù)器進程二者之間傳遞數(shù)據(jù)

客戶端和服務(wù)端通訊模式

UNIX環(huán)境高級編程 進程間通訊
?

?

?

XSI IPC

有三種XSI IP:消息隊列,信號量以及共享存儲

每個內(nèi)核中的IPC結(jié)構(gòu)(消息隊列,信號量和共享內(nèi)存)都有一個非負整數(shù)的 標(biāo)示符(identifier)加以引用

如要向一個消息隊列發(fā)送消息或者從一個消息隊列取消息,只需要知道其隊列標(biāo)識符。

無論何時IPC結(jié)構(gòu)都應(yīng)指向一個鍵,這個鍵的數(shù)據(jù)類型是基本類型是系統(tǒng)數(shù)據(jù)類型key_t,包含在頭文件

<sys/types.h>中

?

有多種方法使客戶進程和服務(wù)器進程再同一IPC結(jié)構(gòu)上匯聚

1)服務(wù)器進程可以指定鍵IPC_PRIVATE創(chuàng)建一個新IPC結(jié)構(gòu),將返回的標(biāo)識符存放在某處(如一個文件)以便

? 客戶進程取用。鍵IPC_PRIVATE保證服務(wù)器進程創(chuàng)建一個新IPC結(jié)構(gòu),這種技術(shù)的缺點: 文件系統(tǒng)操作需要

? 服務(wù)器進程將整型標(biāo)識符寫到文件中,此后客戶進程又要讀這個文件去的此標(biāo)識符

? IPC_PRIVATE鍵也可用于父進程子關(guān)系,父進程指定IPC_PRIVATE創(chuàng)建一個新IPC結(jié)構(gòu),所返回的標(biāo)識符

? 可供fork后的子進程使用。接著子進程又可將此標(biāo)識符為exec函數(shù)的一個參數(shù)傳給一個新程序

2)可以在一個公用頭文件中定義一個客戶進程和服務(wù)器進程都認可的鍵。然后服務(wù)器進程指定此鍵創(chuàng)建一個

? ?新的IPC結(jié)構(gòu),這種方式問題是該鍵可能與一個IP結(jié)構(gòu)相結(jié)合,在此情況下get函數(shù)出錯返回,服務(wù)器進程

? ?必須處理這一錯誤,刪除已存在的IPC結(jié)構(gòu)然后試著再創(chuàng)建它

3)客戶進程和服務(wù)器進程認同一個路徑名和項目ID(項目ID是0--255之間的字符值)接著,調(diào)用函數(shù)fork將兩個

? ?值變換為一個鍵,然后在方法 2)中使用此鍵

XSI IPC權(quán)限

權(quán)限
用戶讀 0400
用戶寫(更改) 0200
組讀 0040
組寫(更改) 0020
其他讀 0004
其他寫(更改) 0002

?

XSI IPC的問題

1)IPC結(jié)構(gòu)是在系統(tǒng)范圍內(nèi)起作用,沒有引用計數(shù),如果進程創(chuàng)建了一個消息隊列,并且在該隊列中放入

? 幾條消息然后終止,那么該消息內(nèi)容不會被刪除,他們會一直留在系統(tǒng)中直至發(fā)生下列動作

? ? ?a)某個進程調(diào)用msgrcv或者msgctl讀消息或刪除消息隊列

? ? ?b)某個進程執(zhí)行ipcrm命令刪除消息隊列

? ? ?c)正在自舉的系統(tǒng)刪除消息隊列

? 與管道消息,當(dāng)最后一個引用管道的進程終止時,管道就被完全刪除了,對FIFO而言,最后一個應(yīng)用FIFO

? 的進程終止時,雖然FIFO的名字仍然保留在系統(tǒng)中直到被顯示的刪除,但是FIFO中的數(shù)據(jù)已被刪除了

2)這些IPC結(jié)構(gòu)在文件系統(tǒng)中沒有名字,不能用文件I/O的方式去訪問和修改他們。為了支持這些IPC對象,

? 內(nèi)核中增加了十幾個全新的系統(tǒng)調(diào)用(msgget,semop,shmat等)我們不能用ls 命令查看IPC對象,不能用

? rm刪除他們,于是又增加了新命令ipcs 和 ipcrm

? 因為這些形式的IP不使用文件描述符,所以不能對他們使用多路轉(zhuǎn)換I/O,這使得它很難一次使用一個以上

? 這樣的IPC結(jié)構(gòu)

?

不同形式IPC之間的特征比較

IPC類型 無連接 可靠地 流控制 記錄 消息類型或優(yōu)先級
消息隊列
STREAMS
UNIX域套接字
UNIX域數(shù)據(jù)報套接字
FIFO(非STREAMS)

?

?

信號量

信號量與已經(jīng)介紹過的IPC結(jié)構(gòu)不同,它是一個計數(shù)器,用于為多個進程提供對共享數(shù)據(jù)對象的訪問

為獲得共享資源,進程需要執(zhí)行下列操作

1)測試控制該資源的信號量

2)若此信號量的值為正,則進程可以使用該資源,在這種情況下進程會將信號量值減1

3)否則若此信號量的值為0,則進程進入休眠狀態(tài),直至信號量大于0,進程被喚醒后返回步驟1)

常用的信號量形式為稱為二元信號量(binary semaphore),它控制單個資源

?

遺憾的是XSI信號量與此相比要復(fù)雜的多,以下三種特性造成了這種不必要的復(fù)雜

1)信號量并非是單個非負值,而必需定義為含有一個或者多個信號量的集合,當(dāng)創(chuàng)建信號量時,要指定集合

? ?中信號量的數(shù)量

2)信號量的創(chuàng)建是獨立于它的初始化的,這是一個致命的缺點,因為不能原子的創(chuàng)建一個信號量集合,并且

? ?對該集合中的各個信號量賦初始值

3)即使么有進程正在使用各種形式的XSI IPC,它們?nèi)匀皇谴嬖诘模械某绦蛟诮K止時并沒有釋放已經(jīng)分配給

? ?它們的信號量

?

?

/dev/zerio的存儲映射

在讀設(shè)備/dev/zero時,該設(shè)備是0字節(jié)無限資源,它也接收寫向它的任何數(shù)據(jù),但是又忽略這些數(shù)據(jù),我們對此設(shè)備作為IPC的興趣在于,當(dāng)對其進行存儲映射時,它具有一些特殊性質(zhì):

1)創(chuàng)建一個未命名的存儲區(qū),其長度是mmap的第二個參數(shù),將其向上取整為系統(tǒng)的最近頁長

2)存儲區(qū)都初始化為0

3)如果多個進程的共同祖先進程對mmap指定了MAP_SHARED標(biāo)志,則這些進程可共享此存儲區(qū)

這種方式優(yōu)點: 在調(diào)用mmap創(chuàng)建映射區(qū)之前,無需再一個實際文件。映射/dev/zero自動創(chuàng)建一個指定長度的

? 營社區(qū)。

這種方式缺點: 它只在兩個相關(guān)進程之間起作用,但在相關(guān)進程之間使用線程可能更簡單

?

進程間共享內(nèi)存的方式

UNIX環(huán)境高級編程 進程間通訊
?

?

?

POSIX信號量接口意在解決XSI信號量接口的幾個缺陷

1)相比于XSI接口,POSIX信號量接口考慮到了更高性能實現(xiàn)

2)POSIX信號量接口使用更簡單,沒有信號量集,在熟悉的文件系統(tǒng)操作后一些接口被模式化了,盡管沒有

? ?要求一定要在文件系統(tǒng)中實現(xiàn),但是一些系統(tǒng)的的確是這么實現(xiàn)的

3)POSIX信號量在刪除時表現(xiàn)更完美,回憶一下,當(dāng)一個XSI信號量被刪時信號量標(biāo)識符會失敗,使用POSIX

? ?信號量時,操作能繼續(xù)正常工作指導(dǎo)該信號量的最后一次引用被釋放

?

POSIX信號量有兩種形式: 命名的和未命名的

它們的差異在于創(chuàng)建和銷毀的形式上,但其他工作一樣

未命名信號量只存在內(nèi)存中,并要求能使用心涼的進程必須可以訪問內(nèi)存,這意味著它們只能應(yīng)用在同一

? 進程的線程,或不同進程中已映射相同內(nèi)存內(nèi)容直到它們的地址空間中的線程

命名信號量可以通過名字訪問,因此可以被任何已知它們名字的進程中的線程使用

?

?

?

參考

進程間通訊機制總結(jié)

UNIX環(huán)境高級編程——進程管理和通信(總結(jié))

?

?

?

?

UNIX環(huán)境高級編程 進程間通訊


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91网站入口 | 国产在线精品一区 | 很黄很暴力深夜爽爽无遮挡 | 美国av在线免费观看 | 69国产精品视频免费 | 亚洲精品久久久久一区二区三 | 国产精品一码二码三码在线 | 国产日韩欧美一区 | 欧美亚洲不卡 | 天天射天天操天天 | 欧美在线一区二区三区 | 久草视频官网 | 男女全黄做爰视频免费看 | 色婷婷精品视频 | 久久中文网| 亚洲AV久久久久久久无码 | 日本一区二区三区中文字幕 | 久久综合一个色综合网 | 高清在线一区二区 | 一级片在线免费观看视频 | 欧美激情视频一区二区免费 | 91视频无限看 | 嫩草国产 | 亚洲欧洲日韩 | 久久精品免费视频观看 | 中国一级大黄大黄大色毛片 | 丝袜天堂 | 欧美1区 | 久久久成人精品 | 二级黄| 亚洲91 | 国产日韩欧美在线观看 | 九一传媒在线观看 | av国产精品 | 国精品日韩欧美一区二区三区 | 天天操天天干天天爽 | 婷婷色综合网 | 男女啪啪免费观看无遮挡动态图片 | 亚洲国产黄色 | 五月天黄色网址 | 久久久久无码国产精品一区 |