導航:首頁 > 源碼編譯 > 通信進程源碼

通信進程源碼

發布時間:2022-08-18 14:59:16

『壹』 使用C++ builder實現進程間的通信

進程間通信 IPC

最簡的方式,用文件嘛,一個寫,一個輪著讀

最經典方式是用 管道 或 消息

最常用方式是用 Unix Socket

最靈活方式是用 Socket 即 走TCP/IP 不但可以實現進程間通信,可以跨主機進行通信

最架構的方式是用 D-Bus IPC框架

『貳』 c++ 進程間通信(管道和共享內存分別寫),給個簡單代碼,包注釋

#include<stdio.h>
#include<windows.h>
intmain(intargc,char*argv[])
{
if(argv[1]==0){//如果是主進程
HANDLEhPipeW,hPipeR;//讀管道和寫管道
STARTUPINFOAsi;
PROCESS_INFORMATIONpi;
charstr[128];
charparam[1024];
CreatePipe(&hPipeR,&hPipeW,NULL,0);
SetHandleInformation(hPipeW,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);//使得子進程可以繼承這個句柄
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
sprintf(param,""%s"%x",argv[0],hPipeW);//傳給子進程的參數
if(CreateProcessA(argv[0],param,0,0,TRUE,0,0,0,&si,&pi)!=FALSE){
char*pstr=str;
CloseHandle(hPipeW);//關閉管道的輸入端,因為此時已經由子進程使用輸入端了
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
for(;;){
DWORDr;
ReadFile(hPipeR,pstr,128,&r,0);//從管道讀取數據
if(r>0)
pstr+=r;
else
break;
}
CloseHandle(hPipeR);
puts(str);
}
return0;
}else{//如果是子進程
charstr[]="Hello!";
HANDLEhPipeW;
DWORDr;
sscanf(argv[1],"%x",&hPipeW);//從參數獲取管道的寫句柄
WriteFile(hPipeW,str,sizeof(str),&r,0);//往管道寫入數據
CloseHandle(hPipeW);
return0;
}
}#include<stdio.h>
#include<string.h>
#include<windows.h>
intmain(intargc,char*argv[])
{
if(argv[1]==0){//如果是作為主進程運行
HANDLEhShmem;
charparam[1024];
STARTUPINFOAsi;
PROCESS_INFORMATIONpi;
char*pstr;
hShmem=CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,256,0);//創建共享內存對象
SetHandleInformation(hShmem,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);//使得句柄可以繼承到子進程

sprintf(param,""%s"%x",argv[0],hShmem);
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
CreateProcessA(argv[0],param,0,0,TRUE,0,0,0,&si,&pi);
WaitForSingleObject(pi.hProcess,INFINITE);//等待子進程運行結束
pstr=(char*)MapViewOfFile(hShmem,FILE_MAP_WRITE,0,0,0);//將共享內存對象中的內存塊映射到當前進程
puts(pstr);
UnmapViewOfFile(pstr);
CloseHandle(hShmem);
return0;
}else{//如果是作為子進程運行
HANDLEhShmem;
char*pstr;
sscanf(argv[1],"%x",&hShmem);
pstr=(char*)MapViewOfFile(hShmem,FILE_MAP_WRITE,0,0,0);//將共享內存對象中的對象映射到當前進程
strcpy(pstr,"Hello~!");//往共享內存里寫入字元串
UnmapViewOfFile(hShmem);
CloseHandle(hShmem);

return0;
}
}

『叄』 linux進程間通信實驗(管道)求源代碼

到CSDN或PSDN去找吧。
比如:
unix環境高級編程源碼
www.pudn.com/downloads190/sourcecode/unix_linux/detail891285.html

『肆』 C內存共享進程通信範例

mmap()範例
下面將給出使用mmap()的兩個範例:範例1給出兩個進程通過映射普通文件實現共享內存通信;範例2給出父子進程通過匿名映射實現共享內存。系統調用mmap()有許多有趣的地方,下面是通過mmap()映射普通文件實現進程間的通信的範例,我們通過該範例來說明mmap()實現共享內存的特點及注意事項。

範例1:兩個進程通過映射普通文件實現共享內存通信

範例1包含兩個子程序:map_normalfile1.c及map_normalfile2.c。編譯兩個程序,可執行文件分別為map_normalfile1及map_normalfile2。兩個程序通過命令行參數指定同一個文件來實現共享內存方式的進程間通信。map_normalfile2試圖打開命令行參數指定的一個普通文件,把該文件映射到進程的地址空間,並對映射後的地址空間進行寫操作。map_normalfile1把命令行參數指定的文件映射到進程地址空間,然後對映射後的地址空間執行讀操作。這樣,兩個進程通過命令行參數指定同一個文件來實現共享內存方式的進程間通信。

下面是兩個程序代碼:

/*-------------map_normalfile1.c-----------*/
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
typedef struct{
char name[4];
int age;
}people;
main(int argc, char** argv) // map a normal file as shared mem:
{
int fd,i;
people *p_map;
char temp;

fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777);
lseek(fd,sizeof(people)*5-1,SEEK_SET);
write(fd,"",1);

p_map = (people*) mmap( NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0 );
close( fd );
temp = 'a';
for(i=0; i<10; i++)
{
temp += 1;
memcpy( ( *(p_map+i) ).name, &temp,2 );
( *(p_map+i) ).age = 20+i;
}
printf(" initialize over \n ");
sleep(10);
munmap( p_map, sizeof(people)*10 );
printf( "umap ok \n" );
}
/*-------------map_normalfile2.c-----------*/
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
typedef struct{
char name[4];
int age;
}people;
main(int argc, char** argv) // map a normal file as shared mem:
{
int fd,i;
people *p_map;
fd=open( argv[1],O_CREAT|O_RDWR,00777 );
p_map = (people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
for(i = 0;i<10;i++)
{
printf( "name: %s age %d;\n",(*(p_map+i)).name, (*(p_map+i)).age );
}
munmap( p_map,sizeof(people)*10 );
}

map_normalfile1.c首先定義了一個people數據結構,(在這里採用數據結構的方式是因為,共享內存區的數據往往是有固定格式的,這由通信的各個進程決定,採用結構的方式有普遍代表性)。map_normfile1首先打開或創建一個文件,並把文件的長度設置為5個people結構大小。然後從mmap()的返回地址開始,設置了10個people結構。然後,進程睡眠10秒鍾,等待其他進程映射同一個文件,最後解除映射。

map_normfile2.c只是簡單的映射一個文件,並以people數據結構的格式從mmap()返回的地址處讀取10個people結構,並輸出讀取的值,然後解除映射。

分別把兩個程序編譯成可執行文件map_normalfile1和map_normalfile2後,在一個終端上先運行./map_normalfile2 /tmp/test_shm,程序輸出結果如下:

initialize over
umap ok

在map_normalfile1輸出initialize over 之後,輸出umap ok之前,在另一個終端上運行map_normalfile2 /tmp/test_shm,將會產生如下輸出(為了節省空間,輸出結果為稍作整理後的結果):

name: b age 20; name: c age 21; name: d age 22; name: e age 23; name: f age 24;
name: g age 25; name: h age 26; name: I age 27; name: j age 28; name: k age 29;

在map_normalfile1 輸出umap ok後,運行map_normalfile2則輸出如下結果:

name: b age 20; name: c age 21; name: d age 22; name: e age 23; name: f age 24;
name: age 0; name: age 0; name: age 0; name: age 0; name: age 0;

從程序的運行結果中可以得出的結論

1、 最終被映射文件的內容的長度不會超過文件本身的初始大小,即映射不能改變文件的大小;

2、 可以用於進程通信的有效地址空間大小大體上受限於被映射文件的大小,但不完全受限於文件大小。打開文件被截短為5個people結構大小,而在map_normalfile1中初始化了10個people數據結構,在恰當時候(map_normalfile1輸出initialize over 之後,輸出umap ok之前)調用map_normalfile2會發現map_normalfile2將輸出全部10個people結構的值,後面將給出詳細討論。
註:在linux中,內存的保護是以頁為基本單位的,即使被映射文件只有一個位元組大小,內核也會為映射分配一個頁面大小的內存。當被映射文件小於一個頁面大小時,進程可以對從mmap()返回地址開始的一個頁面大小進行訪問,而不會出錯;但是,如果對一個頁面以外的地址空間進行訪問,則導致錯誤發生,後面將進一步描述。因此,可用於進程間通信的有效地址空間大小不會超過文件大小及一個頁面大小的和。

3、 文件一旦被映射後,調用mmap()的進程對返回地址的訪問是對某一內存區域的訪問,暫時脫離了磁碟上文件的影響。所有對mmap()返回地址空間的操作只在內存中有意義,只有在調用了munmap()後或者msync()時,才把內存中的相應內容寫回磁碟文件,所寫內容仍然不能超過文件的大小。

範例2:父子進程通過匿名映射實現共享內存

#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
typedef struct{
char name[4];
int age;
}people;
main(int argc, char** argv)
{
int i;
people *p_map;
char temp;
p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
if(fork() == 0)
{
sleep(2);
for(i = 0;i<5;i++)
printf("child read: the %d people's age is %d\n",i+1,(*(p_map+i)).age);
(*p_map).age = 100;
munmap(p_map,sizeof(people)*10); //實際上,進程終止時,會自動解除映射。
exit();
}
temp = 'a';
for(i = 0;i<5;i++)
{
temp += 1;
memcpy((*(p_map+i)).name, &temp,2);
(*(p_map+i)).age=20+i;
}
sleep(5);
printf( "parent read: the first people,s age is %d\n",(*p_map).age );
printf("umap\n");
munmap( p_map,sizeof(people)*10 );
printf( "umap ok\n" );
}

考察程序的輸出結果,體會父子進程匿名共享內存:

child read: the 1 people's age is 20
child read: the 2 people's age is 21
child read: the 3 people's age is 22
child read: the 4 people's age is 23
child read: the 5 people's age is 24
parent read: the first people,s age is 100
umap
umap ok

回頁首

四、對mmap()返回地址的訪問

前面對範例運行結構的討論中已經提到,linux採用的是頁式管理機制。對於用mmap()映射普通文件來說,進程會在自己的地址空間新增一塊空間,空間大小由mmap()的len參數指定,注意,進程並不一定能夠對全部新增空間都能進行有效訪問。進程能夠訪問的有效地址大小取決於文件被映射部分的大小。簡單的說,能夠容納文件被映射部分大小的最少頁面個數決定了進程從mmap()返回的地址開始,能夠有效訪問的地址空間大小。超過這個空間大小,內核會根據超過的嚴重程度返回發送不同的信號給進程。可用如下圖示說明:

注意:文件被映射部分而不是整個文件決定了進程能夠訪問的空間大小,另外,如果指定文件的偏移部分,一定要注意為頁面大小的整數倍。下面是對進程映射地址空間的訪問範例:

#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
typedef struct{
char name[4];
int age;
}people;
main(int argc, char** argv)
{
int fd,i;
int pagesize,offset;
people *p_map;

pagesize = sysconf(_SC_PAGESIZE);
printf("pagesize is %d\n",pagesize);
fd = open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777);
lseek(fd,pagesize*2-100,SEEK_SET);
write(fd,"",1);
offset = 0; //此處offset = 0編譯成版本1;offset = pagesize編譯成版本2
p_map = (people*)mmap(NULL,pagesize*3,PROT_READ|PROT_WRITE,MAP_SHARED,fd,offset);
close(fd);

for(i = 1; i<10; i++)
{
(*(p_map+pagesize/sizeof(people)*i-2)).age = 100;
printf("access page %d over\n",i);
(*(p_map+pagesize/sizeof(people)*i-1)).age = 100;
printf("access page %d edge over, now begin to access page %d\n",i, i+1);
(*(p_map+pagesize/sizeof(people)*i)).age = 100;
printf("access page %d over\n",i+1);
}
munmap(p_map,sizeof(people)*10);
}

如程序中所注釋的那樣,把程序編譯成兩個版本,兩個版本主要體現在文件被映射部分的大小不同。文件的大小介於一個頁面與兩個頁面之間(大小為:pagesize*2-99),版本1的被映射部分是整個文件,版本2的文件被映射部分是文件大小減去一個頁面後的剩餘部分,不到一個頁面大小(大小為:pagesize-99)。程序中試圖訪問每一個頁面邊界,兩個版本都試圖在進程空間中映射pagesize*3的位元組數。

版本1的輸出結果如下:

pagesize is 4096
access page 1 over
access page 1 edge over, now begin to access page 2
access page 2 over
access page 2 over
access page 2 edge over, now begin to access page 3
Bus error //被映射文件在進程空間中覆蓋了兩個頁面,此時,進程試圖訪問第三個頁面

版本2的輸出結果如下:

pagesize is 4096
access page 1 over
access page 1 edge over, now begin to access page 2
Bus error //被映射文件在進程空間中覆蓋了一個頁面,此時,進程試圖訪問第二個頁面

結論:採用系統調用mmap()實現進程間通信是很方便的,在應用層上介面非常簡潔。內部實現機制區涉及到了linux存儲管理以及文件系統等方面的內容,可以參考一下相關重要數據結構來加深理解。在本專題的後面部分,將介紹系統v共享內存的實現。

參考資料

[1] Understanding the Linux Kernel, 2nd Edition, By Daniel P. Bovet, Marco Cesati , 對各主題闡述得重點突出,脈絡清晰。

[2] UNIX網路編程第二卷:進程間通信,作者:W.Richard Stevens,譯者:楊繼張,清華大學出版社。對mmap()有詳細闡述。

[3] Linux內核源代碼情景分析(上),毛德操、胡希明著,浙江大學出版社,給出了mmap()相關的源代碼分析。

[4]mmap()手冊

『伍』 一個進程通信 的 linux程序編寫

學習步驟如下:

1、Linux 基礎

安裝Linux操作系統
Linux文件系統
Linux常用命令
Linux啟動過程詳解
熟悉Linux服務能夠獨立安裝Linux操作系統
能夠熟練使用Linux系統的基本命令
認識Linux系統的常用服務安裝Linux操作系統
Linux基本命令實踐
設置Linux環境變數
定製Linux的服務 Shell 編程基礎使用vi編輯文件
使用Emacs編輯文件
使用其他編輯器

2、Shell 編程基礎

Shell簡介
認識後台程序
Bash編程熟悉Linux系統下的編輯環境
熟悉Linux下的各種Shell
熟練進行shell編程熟悉vi基本操作
熟悉Emacs的基本操作
比較不同shell的區別
編寫一個測試伺服器是否連通的shell腳本程序
編寫一個查看進程是否存在的shell腳本程序
編寫一個帶有循環語句的shell腳本程序

3、Linux 下的 C 編程基礎

linux C語言環境概述
Gcc使用方法
Gdb調試技術
Autoconf
Automake
Makefile
代碼優化 熟悉Linux系統下的開發環境
熟悉Gcc編譯器
熟悉Makefile規則編寫Hello,World程序
使用 make命令編譯程序
編寫帶有一個循環的程序
調試一個有問題的程序

4、嵌入式系統開發基礎

嵌入式系統概述
交叉編譯
配置TFTP服務
配置NFS服務
下載Bootloader和內核
嵌入式Linux應用軟體開發流程
熟悉嵌入式系統概念以及開發流程
建立嵌入式系統開發環境製作cross_gcc工具鏈
編譯並下載U-boot
編譯並下載Linux內核
編譯並下載Linux應用程序
嵌入式系統移植
Linux內核代碼
平台相關代碼分析
ARM平台介紹
平台移植的關鍵技術
移植Linux內核到 ARM平台 了解移植的概念
能夠移植Linux內核移植Linux2.6內核到 ARM9開發板

5、嵌入式 Linux 下串口通信

串列I/O的基本概念
嵌入式Linux應用軟體開發流程
Linux系統的文件和設備
與文件相關的系統調用
配置超級終端和MiniCOM 能夠熟悉進行串口通信
熟悉文件I/O 編寫串口通信程序
編寫多串口通信程序

6、嵌入式系統中多進程程序設計

Linux系統進程概述
嵌入式系統的進程特點
進程操作
守護進程
相關的系統調用了解Linux系統中進程的概念
能夠編寫多進程程序編寫多進程程序
編寫一個守護進程程序
sleep系統調用任務管理、同步與通信 Linux任務概述
任務調度
管道
信號
共享內存
任務管理 API 了解Linux系統任務管理機制
熟悉進程間通信的幾種方式
熟悉嵌入式Linux中的任務間同步與通信
編寫一個簡單的管道程序實現文件傳輸
編寫一個使用共享內存的程序

7、嵌入式系統中多線程程序設計

線程的基礎知識
多線程編程方法
線程應用中的同步問題了解線程的概念
能夠編寫簡單的多線程程序編寫一個多線程程序

8、嵌入式 Linux 網路編程

網路基礎知識
嵌入式Linux中TCP/IP網路結構
socket 編程
常用 API函數
分析Ping命令的實現
基本UDP套介面編程
許可證管理
PPP協議
GPRS 了解嵌入式Linux網路體系結構
能夠進行嵌入式Linux環境下的socket 編程
熟悉UDP協議、PPP協議
熟悉GPRS 使用socket 編寫代理伺服器
使用socket 編寫路由器
編寫許可證伺服器
指出TCP和UDP的優缺點
編寫一個web伺服器
編寫一個運行在 ARM平台的網路播放器

9、GUI 程序開發

GUI基礎
嵌入式系統GUI類型
編譯QT
進行QT開發熟悉嵌入式系統常用的GUI
能夠進行QT編程使用QT編寫「Hello,World」程序
調試一個加入信號/槽的實例
通過重載QWidget 類方法處理事件

10、Linux 字元設備驅動程序

設備驅動程序基礎知識
Linux系統的模塊
字元設備驅動分析
fs_operation結構
載入驅動程序了解設備驅動程序的概念
了解Linux字元設備驅動程序結構
能夠編寫字元設備驅動程序編寫Skull驅動
編寫鍵盤驅動
編寫I/O驅動
分析一個看門狗驅動程序
對比Linux2.6內核與2.4內核中字元設備驅動的不同
Linux 塊設備驅動程序塊設備驅動程序工作原理
典型的塊設備驅動程序分析
塊設備的讀寫請求隊列了解Linux塊設備驅動程序結構
能夠編寫簡單的塊設備驅動程序比較字元設備與塊設備的異同
編寫MMC卡驅動程序
分析一個文件系統
對比Linux2.6內核與2.4內核中塊設備驅動的不同

11、文件系統

虛擬文件系統
文件系統的建立
ramfs內存文件系統
proc文件系統
devfs 文件系統
MTD技術簡介
MTD塊設備初始化
MTD塊設備的讀寫操作了解Linux系統的文件系統
了解嵌入式Linux的文件系統
了解MTD技術
能夠編寫簡單的文件系統為 ARM9開發板添加 MTD支持
移植JFFS2文件系統
通過proc文件系統修改操作系統參數
分析romfs 文件系統源代碼
創建一個cramfs 文件系統

『陸』 寫進程間通信模擬的代碼,要求實現管道通信與消息通信兩種方式. 界面簡單,易懂,關鍵代碼部分要注釋.

通俗點說,進程是一個具體的應用程序,WINDOWS中每個程序對應一個進程,就象是我們線個人都有一個身份證號碼,獨一無二的。
線程是進程中的一個分支,為單獨完成程序中的某一項或一組功能而存在。
應用程序可以有一個或多個進程,一個進程可以有一個或多個線程,其中一個是主線程。

閱讀全文

與通信進程源碼相關的資料

熱點內容
多女主免費閱讀 瀏覽:49
前端程序員選擇極客時間 瀏覽:164
php我要自學網 瀏覽:201
a盤命令 瀏覽:706
日俄加密通話 瀏覽:660
linuxtee命令 瀏覽:53
pdf程序員找不到了 瀏覽:63
全球票房實時查詢 瀏覽:223
伺服器如何添加域用戶 瀏覽:271
java靜態static 瀏覽:227
程序員容易掉頭發嗎 瀏覽:333
python通用管理系統 瀏覽:204
apachephphtml 瀏覽:141
安慶智能雲伺服器找哪家 瀏覽:763
linuxtab輸入 瀏覽:932
小說網盤資源 瀏覽:504
全免費影視投屏網站 瀏覽:254
娘娘懷孕快生了忍著不生 瀏覽:804
git拉取代碼的命令 瀏覽:995
程序員節西安市 瀏覽:687