每個進程各自有不同的用戶地址空間,任何一個進 程的全局變量在另一個進程中都看不到,所以進程之間要交換數據必須通過內核,在內核中開闢一塊緩衝 區,進程1把數據從用戶空間拷到內核緩衝區,進程2再從內核緩衝區把數據讀走,內核提供的這種機制稱爲進程間通信(IPC,InterProcess Communication)
# 有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
# 信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
# 消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
# 共享內存( shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
IPC_CREAT 新建(如果已創建則返回目前共享內存的id)
IPC_EXCL 與IPC_CREAT結合使用,如果已創建則則返回錯誤
參數說明:
cmd:控制命令,可取值如下:
IPC_STAT 得到共享內存的狀態
IPC_SET 改變共享內存的狀態
IPC_RMID 刪除共享內存
buf:一個結構體指針。用以保存/設置屬性。IPC_STAT的時候,取得的狀態放在這個結構體中。如果要改變共享內存的狀態,用這個結構體指定。
返回值:成功時返回0。失敗時返回-1。
-
/*name:writer.c
-
*function:寫端進程向共享內存寫數據
-
* */
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <errno.h>
-
#include <signal.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/ipc.h>
-
#include <sys/shm.h>
-
-
#define N 64
-
-
typedef struct
-
{
-
pid_t pid;
-
char buf[N];
-
} SHM;
-
-
void handler(int signo)
-
{
-
//printf("get
signal\n");
-
return;
-
}
-
-
int main()
-
{
-
key_t key;
-
int shmid;
-
SHM *p;
-
pid_t pid;
-
-
if ((key = ftok(".", 'm')) < 0)
-
{
-
perror("fail to ftok");
-
exit(-1);
-
}
-
-
signal(SIGUSR1, handler);//註冊一個信號處理函數
-
if ((shmid = shmget(key, sizeof(SHM), 0666|IPC_CREAT|IPC_EXCL)) < 0)
-
{
-
if (EEXIST == errno)//存在則直接打開
-
{
-
shmid = shmget(key, sizeof(SHM), 0666);
-
p = (SHM *)shmat(shmid, NULL, 0);
-
pid = p->pid;
-
p->pid = getpid();
-
kill(pid, SIGUSR1);
-
}
-
else//出錯
-
{
-
perror("fail to shmget");
-
exit(-1);
-
}
-
}
-
else//成功
-
{
-
p = (SHM *)shmat(shmid, NULL, 0);
-
p->pid = getpid();//把自己的pid寫到共享內存
-
pause();
-
pid = p->pid;//得到讀端進程的pid
-
}
-
-
while ( 1 )
-
{
-
printf("write to shm : ");
-
fgets(p->buf, N, stdin);//接收輸入
-
kill(pid, SIGUSR1);//向讀進程發SIGUSR1信號
-
if (strcmp(p->buf, "quit\n") == 0) break;
-
pause();//阻塞,等待信號
-
}
-
shmdt(p);
-
shmctl(shmid, IPC_RMID, NULL);//刪除共享內存
-
-
return 0;
- }
-
/*name:reader.c
-
*function:讀端進程從共享內存中讀數據
-
* */
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <errno.h>
-
#include <signal.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/ipc.h>
-
#include <sys/shm.h>
-
-
#define N 64
-
-
typedef struct
-
{
-
pid_t pid;
-
char buf[N];
-
} SHM;
-
-
void handler(int signo)
-
{
-
//printf("get
signal\n");
-
return;
-
}
-
-
int main()
-
{
-
key_t key;
-
int shmid;
-
SHM *p;
-
pid_t pid;
-
-
if ((key = ftok(".", 'm')) < 0)
-
{
-
perror("fail to ftok");
-
exit(-1);
-
}
-
-
signal(SIGUSR1, handler);//註冊一個信號處理函數
-
if ((shmid = shmget(key, sizeof(SHM), 0666|IPC_CREAT|IPC_EXCL)) < 0)
-
{
-
if (EEXIST == errno)//存在則直接打開
-
{
-
shmid = shmget(key, sizeof(SHM), 0666);
-
p = (SHM *)shmat(shmid, NULL, 0);
-
pid = p->pid;
-
p->pid = getpid();//把自己的pid寫到共享內存
-
kill(pid, SIGUSR1);
-
}
-
else//出錯
-
{
-
perror("fail to shmget");
-
exit(-1);
-
}
-
}
-
else//成功
-
{
-
p = (SHM *)shmat(shmid, NULL, 0);
-
p->pid = getpid();
-
pause();
-
pid = p->pid;//得到寫端進程的pid
-
}
-
-
while ( 1 )
-
{
-
pause();//阻塞,等待信號
-
if (strcmp(p->buf, "quit\n") == 0) exit(0);//輸入"quit結束"
-
printf("read from shm : %s", p->buf);
-
kill(pid, SIGUSR1);//向寫進程發SIGUSR1信號
-
}
-
-
return 0;
- }