管道,消息隊列,共享內存!

2015.1.26
星期一,陰天linux

linux中使用的較多的進程通訊方式主要有一下幾種:
1.管道(Pipe):管道可用於具備親緣關係進程間的通訊,有名管道,除了具備管道所具備功能外,它
還容許無親緣關係進程的通訊
2.信號(signal):信號是在軟件層次上對中斷機制的一種模擬,它是比較複雜的通訊方式,用於通知進程
有某事發生,一個進程收到一個信號與處理器收到一箇中斷請求效果上能夠說是同樣的
3.消息隊列:(Messge Queue):消息隊列是消息的鏈接表,包括Posix消息隊列SystemV消息隊列,它克服了前兩種通訊方式中信息量有限的
的缺點,具備寫權限的進程能夠按照必定的規劃向消息隊列中添加新的消息,對消息隊列有讀權限的進程則能夠從
消息隊列中讀取消息
4.共享內存(Shared memory):能夠說這是最有用的進程通訊方式,它使得多個進程能夠訪問同一塊內存空間,
不一樣進程能夠及時看到對方進程中對共享內存中數據的更新,這種通訊方式須要依靠某種同步機制,如互斥鎖和信號量等
5.信號量(Semaphore):主要做爲進程之間以及同一進程的不一樣線程之間的同步和互斥手段
5.套接字(Socket):這是一種更爲通常的進程通訊機制,他是可用於網絡中不一樣機器之間的進程通訊,應用很是普遍,網絡

1.管道系統的調用:
管道是基於文件描述符的通訊方式,當一個管道創建時,他會建立兩個文件描述符fds[0](固定用於讀管道),fds[1](固定用於寫管道)
管道關閉時只須要將這兩個文件描述符關閉便可,可使用普通的close()函數逐個關閉各個文件描述符函數

2.管道建立函數
int pipe(int fd[2]) 成功:0,出錯:-1學習

5.管道讀寫注意點
1.只有在管道的讀端存在時,向管道寫入數據纔有意義,不然,向管道寫入數據的進程將收到內核傳來的
SIGPIPE信號(一般爲Broken pipe錯誤)
2.向管道寫入數據時,linux將不保證寫入的原子性,管道緩衝區有空閒區域,寫進程就會試圖向管道寫入數據,如
果讀進程不讀取管道緩衝區中的數據,那麼寫操做將會一直阻塞。
3.父子進程在運行時,他們的前後次序並不能保證,所以,在這裏爲了保證父子進程已經關閉了相應的
文件描述符,可在兩個進程中調用sleep()函數,但這不是很好的方法,,可參考進程同步和互斥機制線程

下面是今天分析的一些程序:視頻

消息隊列的發送和寫入程序:隊列

#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>進程

struct msg_buf
{
int mtype;
char data[255];
};ip

int main()
{
key_t key;
int msgid;
int ret;
struct msg_buf msgbut;內存

key = ftok("/tmp/2",'a'); 得到鍵值
printf("key = [%x]\n",key);
msgid = msgget(key,IPC_CRREAT|0666);

if(msgid == -1)
{
printf("create error\n");
return -1;
}

msgbuf.mtype = getpid();
strcpy(msgbuf.data,"test haha");
ret = msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT); 發送信息
if(ret == -1)
{
printf("send message err\n");
return -1;
}

memset(&msgbuf,0,sizeof(msgbuf));
ret = msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT); 讀取信息
if (ret==-1)
{
printf("recv message err\n");
return -1;
}

printf("recv msg = [%s]\n",msgbuf.data);
}

共享內存的一段程序:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define PERM S_IRUSR|S_IWUSR

int main(int argc, char **argv)
{
int shmid;
char *p_addr,*c_addr;

if(argc != 2)
{
fprintf(stderr,"usage:%s\n\a",argv[0]);
exit(1);
}

if((shmid = shmget(IPC_PRIVATE,1024,PERM)) == -1)
{
fprintf(stderr,"Create share Memory error:%s\n\a",strerror(errno));
exit(1);
}

if(fork())
{
p_addr = shmat(shmid ,0, 0);
memset(p_addr,'\0',1024);
strncpy(p_addr,argv[1],1024);
wait(NULL);
exit(0);

}
else
{
sleep(1);
c_addr = shmat(shmid, 0, 0);
printf("client get %s\n",c_addr);
exit(0);
}

}

今天老師沒有上課,上午和班級同窗分享了之前作光立方的那段經歷,講了半個小時吧,好多想表達的意思沒表達出來,
這是一個弱點,另外一方法也反映本身有寫只是掌握的不是很牢固,須要繼續學習。整理了上個星期老師上課的知識點,統計
了一下同窗們不怎麼明白的一些知識點,而後交給了老師,上午很快就結束了。作的事很少,可是到講臺上鍛鍊了一下本身
的表達能力。下午看了四個視頻,都是關於進程通訊的,包括管道和共享內存,程序基本能懂,還須要聯繫,如今咱們的課程還
沒上到這裏,沒有資料書,看PDF很差查函數的用法,上下找很麻煩。回去借點書看,明天我想看ARM的基礎知識了!

******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************

相關文章
相關標籤/搜索