本文目錄一覽:
- 1、如何用C#實現進程間通信
- 2、如何用C語言實現採用共享內存的進程間通信
- 3、VC++ 進程間的通信
- 4、linux下進程通信 C語言編寫
- 5、linux下c的兩個進程如何實現通信?一個進程給另一個進程發送消息,另一個接受並顯示出來。求大神啊
- 6、利用C語言寫一個程序實現兩個進程間進行管道通信
如何用C#實現進程間通信
C#中建議用WCF,本地通信使用管道通信(並非必須),網絡通信用TCP綁定。前提是你要知道WCF的基本概念。
service服務(包括web service)可以運行在任何一個.Net excutable上並且需要通過Interface調用,你可以把這個服務集成到你的本地窗體應用程序里,這樣在本地你就不需要進程間的通信了,節省很多工作量。如果非要分開,那麼要麼在你的本地窗體應用程序里新開一個Service來服務你的WebService,要麼調用底層SDK函數獲取窗體句柄然後發消息。當然還有其他的方式,比如文件共享、數據庫共享等。
另外看你的描述,「新建一個又新建一個」,如果這是你設計的系統結構,那麼建議你重新設計,好的軟件是在需求明確的情況下設計出來的,編程再其次。
如何用C語言實現採用共享內存的進程間通信
共享內存的函數有以下幾個:
(1)int shmget(key_t key, int size, int shmflg),開闢或使用一塊共享內存。
(2)void *shmat(int shmid, const void *shmaddr, int shmflg), 將參數shmid所指向的共享內存與當前進程連接。
當使用某共享內存時,需要先使用shmat,達成連接。
(3)int shmdt(const void *shmaddr),將先前用shmat連接的共享內存與當前進程解除連接。參數shmaddr為shmat返回的共享內存的地址。
在完成對共享內存的使用後,需要使用shmdt解除連接。
(4)int shmctl(int shmid, int cmd, struct shmid_ds *buf),控制內存的操作。當cmd為IPC_RMID時,刪除shmid所指的共享內存。
這些函數的表頭文件為sys/ipc.h和sys/shm.h
下面給出一個使用共享內存實現進程間通信的例子:進程A開闢一塊新的共享內存,進程B修改這個共享內存,進程C打印輸出這個共享內存的內容,進程D刪除這個共享內存。
進程BCD運行的命令格式為:命令 共享內存ID,如./output 123432。
進程A代碼如下:
int main()
{
int shmid;
shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT | 0600);
if (shmid 0)
{
perror(“shmget error”);
exit(1);
}
printf(“create shared memory OK. shmid=%d/n”, shmid);
return 0;
}
進程B代碼如下:
int main(int argc, char *argv[])
{
int shmid;
char *shmaddr;
if (argc != 2)
{
perror(“argc error/n”);
exit(1);
}
shmid = atoi(argv[1]);
shmaddr = (char *)shmat(shmid, NULL, 0);
if ((int )shmaddr == -1)
{
perror(“shmat error./n”);
exit(1);
}
strcpy(shmaddr, “hello, world!”);
shmdt(shmaddr);
return 0;
}
進程C代碼如下:
int main(int argc, char *argv[])
{
int shmid;
char *shmaddr;
if (argc != 2)
{
printf(“argc error/n”);
exit(1);
}
shmid = atoi(argv[1]);
shmaddr = (char *)shmat(shmid, NULL, 0);
if ((int )shmaddr == -1)
{
perror(“shmat error./n”);
exit(1);
}
printf(“%s/n”, shmaddr);
shmdt(shmaddr);
return 0;
}
進程D代碼如下:
int main(int argc, char *argv[])
{
int shmid;
if (argc != 2)
{
perror(“argc error/n”);
exit(1);
}
shmid = atoi(argv[1]);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
VC++ 進程間的通信
線程間通訊
一般而言,應用程序中的一個次要線程總是為主線程執行特定的任務,這樣,主線程和次要線程間必定有一個信息傳遞的渠道,也就是主線程和次要線程間要進行通信。這種線程間的通信不但是難以避免的,而且在多線程編程中也是複雜和頻繁的,下面將進行說明。
使用全局變量進行通信
由於屬於同一個進程的各個線程共享操作系統分配該進程的資源,故解決線程間通信最簡單的一種方法是使用全局變量。對於標準類型的全局變量,我們建議使用volatile 修飾符,它告訴編譯器無需對該變量作任何的優化,即無需將它放到一個寄存器中,並且該值可被外部改變。如果線程間所需傳遞的信息較複雜,我們可以定義一個結構,通過傳遞指向該結構的指針進行傳遞信息。
使用自定義消息
我們可以在一個線程的執行函數中向另一個線程發送自定義的消息來達到通信的目的。一個線程向另外一個線程發送消息是通過操作系統實現的。利用Windows操作系統的消息驅動機制,當一個線程發出一條消息時,操作系統首先接收到該消息,然後把該消息轉發給目標線程,接收消息的線程必須已經建立了消息循環。
例程7 MultiThread7
該例程演示了如何使用自定義消息進行線程間通信。首先,主線程向CCalculateThread線程發送消息WM_CALCULATE,CCalculateThread線程收到消息後進行計算,再向主線程發送WM_DISPLAY消息,主線程收到該消息後顯示計算結果。
建立一個基於對話框的工程MultiThread7,在對話框IDD_MULTITHREAD7_DIALOG中加入三個單選按鈕IDC_RADIO1,IDC_RADIO2,IDC_RADIO3,標題分別為1+2+3+4+……+10,1+2+3+4+……+50,1+2+3+4+……+100。加入按鈕IDC_SUM,標題為「求和」。加入標籤框IDC_STATUS,屬性選中「邊框」;
在MultiThread7Dlg.h中定義如下變量: protected:
int nAddend;
代表加數的大小。
分別雙擊三個單選按鈕,添加消息響應函數:void CMultiThread7Dlg::OnRadio1()
{
nAddend=10;
}
void CMultiThread7Dlg::OnRadio2()
{
nAddend=50;
}
void CMultiThread7Dlg::OnRadio3()
{
nAddend=100;
}
並在OnInitDialog函數中完成相應的初始化工作: BOOL CMultiThread7Dlg::OnInitDialog()
{
……
((CButton*)GetDlgItem(IDC_RADIO1))-SetCheck(TRUE);
nAddend=10;
……
在MultiThread7Dlg.h中添加: #include “CalculateThread.h”
#define WM_DISPLAY WM_USER+2
class CMultiThread7Dlg : public CDialog
{
// Construction
public:
CMultiThread7Dlg(CWnd* pParent = NULL); // standard constructor
CCalculateThread* m_pCalculateThread;
……
protected:
int nAddend;
LRESULT OnDisplay(WPARAM wParam,LPARAM lParam);
……
在MultiThread7Dlg.cpp中添加: BEGIN_MESSAGE_MAP(CMultiThread7Dlg, CDialog)
……
ON_MESSAGE(WM_DISPLAY,OnDisplay)
END_MESSAGE_MAP()
LRESULT CMultiThread7Dlg::OnDisplay(WPARAM wParam,LPARAM lParam)
{
int nTemp=(int)wParam;
SetDlgItemInt(IDC_STATUS,nTemp,FALSE);
return 0;
}
以上代碼使得主線程類CMultiThread7Dlg可以處理WM_DISPLAY消息,即在IDC_STATUS標籤框中顯示計算結果。
雙擊按鈕IDC_SUM,添加消息響應函數: void CMultiThread7Dlg::OnSum()
{
m_pCalculateThread=
(CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));
Sleep(500);
m_pCalculateThread-PostThreadMessage(WM_CALCULATE,nAddend,NULL);
}
OnSum()函數的作用是建立CalculateThread線程,延時給該線程發送WM_CALCULATE消息。
右擊工程並選中「New Class…」為工程添加基類為 CWinThread 派生線程類 CCalculateThread。
在文件CalculateThread.h 中添加 #define WM_CALCULATE WM_USER+1
class CCalculateThread : public CWinThread
{
……
protected:
afx_msg LONG OnCalculate(UINT wParam,LONG lParam);
……
在文件CalculateThread.cpp中添加 LONG CCalculateThread::OnCalculate(UINT wParam,LONG lParam)
{
int nTmpt=0;
for(int i=0;i=(int)wParam;i++)
{
nTmpt=nTmpt+i;
}
Sleep(500);
::PostMessage((HWND)(GetMainWnd()-GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);
return 0;
}
BEGIN_MESSAGE_MAP(CCalculateThread, CWinThread)
//{{AFX_MSG_MAP(CCalculateThread)
// NOTE – the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)
//和主線程對比,注意它們的區別
END_MESSAGE_MAP()
在CalculateThread.cpp文件的開頭添加一條: #include “MultiThread7Dlg.h”
以上代碼為 CCalculateThread 類添加了 WM_CALCULATE 消息,消息的響應函數是 OnCalculate,其功能是根據參數 wParam 的值,進行累加,累加結果在臨時變量nTmpt中,延時0.5秒,向主線程發送WM_DISPLAY消息進行顯示,nTmpt作為參數傳遞。
編譯並運行該例程,體會如何在線程間傳遞消息。
linux下進程通信 C語言編寫
這個真有點難度,linux下幾乎只有標準C語言,沒有像VC那樣被修改了標準的語言,所以可以認為linux下的C語言都是標準的。 這個程序要是所有的代碼都自己寫的話,會非常複雜的,並且操作系統也不允許你寫這樣的程序…
linux下c的兩個進程如何實現通信?一個進程給另一個進程發送消息,另一個接受並顯示出來。求大神啊
linux中的進程通信分為三個部分:低級通信,管道通信和進程間通信IPC(inter process communication)。linux的低級通信主要用來傳遞進程的控制信號——文件鎖和軟中斷信號機制。linux的進程間通信IPC有三個部分——①信號量,②共享內存和③消息隊列。以下是我編寫的linux進程通信的C語言實現代碼。操作系統為redhat9.0,編輯器為vi,編譯器採用gcc。下面所有實現代碼均已經通過測試,運行無誤。
一.低級通信–信號通信
signal.c
#include signal.h
#include stdio.h
#include unistd.h
/*捕捉到信號sig之後,執行預先預定的動作函數*/
void sig_alarm(int sig)
{
printf(“—the signal received is %d. /n”, sig);
signal(SIGINT, SIG_DFL); //SIGINT終端中斷信號,SIG_DFL:恢復默認行為,SIN_IGN:忽略信號
}
int main()
{
signal(SIGINT, sig_alarm);//捕捉終端中斷信號
while(1)
{
printf(“waiting here!/n”);
sleep(1);
}
return 0;
}
二.管道通信
pipe.c
#include stdio.h
#define BUFFER_SIZE 30
int main()
{
int x;
int fd[2];
char buf[BUFFER_SIZE];
char s[BUFFER_SIZE];
pipe(fd);//創建管道
while((x=fork())==-1);//創建管道失敗時,進入循環
/*進入子進程,子進程向管道中寫入一個字符串*/
if(x==0)
{
sprintf(buf,”This is an example of pipe!/n”);
write(fd[1],buf,BUFFER_SIZE);
exit(0);
}
/*進入父進程,父進程從管道的另一端讀出剛才寫入的字符串*/
else
{
wait(0);//等待子進程結束
read(fd[0],s,BUFFER_SIZE);//讀出字符串,並將其儲存在char s[]中
printf(“%s”,s);//打印字符串
}
return 0;
}
三.進程間通信——IPC
①信號量通信
sem.c
#include unistd.h
#include stdlib.h
#include stdio.h
#include sys/types.h
#include sys/ipc.h
#include sys/sem.h
/*聯合體變量*/
union semun
{
int val; //信號量初始值
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
/*函數聲明,信號量定義*/
static int set_semvalue(void); //設置信號量
static void del_semvalue(void);//刪除信號量
static int semaphore_p(void); //執行P操作
static int semaphore_v(void); //執行V操作
static int sem_id; //信號量標識符
int main(int argc, char *argv[])
{
int i;
int pause_time;
char op_char = ‘O’;
srand((unsigned int)getpid());
sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);//創建一個信號量,IPC_CREAT表示創建一個新的信號量
/*如果有參數,設置信號量,修改字符*/
if (argc 1)
{
if (!set_semvalue())
{
fprintf(stderr, “Failed to initialize semaphore/n”);
exit(EXIT_FAILURE);
}
op_char = ‘X’;
sleep(5);
}
for(i = 0; i 10; i++)
{
/*執行P操作*/
if (!semaphore_p())
exit(EXIT_FAILURE);
printf(“%c”, op_char);
fflush(stdout);
pause_time = rand() % 3;
sleep(pause_time);
printf(“%c”, op_char);
fflush(stdout);
/*執行V操作*/
if (!semaphore_v())
exit(EXIT_FAILURE);
pause_time = rand() % 2;
sleep(pause_time);
}
printf(“/n%d – finished/n”, getpid());
if (argc 1)
{
sleep(10);
del_semvalue(); //刪除信號量
}
exit(EXIT_SUCCESS);
}
/*設置信號量*/
static int set_semvalue(void)
{
union semun sem_union;
sem_union.val = 1;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
return(0);
return(1);
}
/*刪除信號量*/
static void del_semvalue(void)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
fprintf(stderr, “Failed to delete semaphore/n”);
}
/*執行P操作*/
static int semaphore_p(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, sem_b, 1) == -1)
{
fprintf(stderr, “semaphore_p failed/n”);
return(0);
}
return(1);
}
/*執行V操作*/
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, sem_b, 1) == -1)
{
fprintf(stderr, “semaphore_v failed/n”);
return(0);
}
return(1);
}
②消息隊列通信
send.c
#include stdlib.h
#include stdio.h
#include string.h
#include errno.h
#include unistd.h
#include sys/types.h
#include sys/ipc.h
#include sys/msg.h
#define MAX_TEXT 512
/*用於消息收發的結構體–my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[MAX_TEXT];
};
int main()
{
int running = 1;//程序運行標識符
struct my_msg_st some_data;
int msgid;//消息隊列標識符
char buffer[BUFSIZ];
/*創建與接受者相同的消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, “msgget failed with error: %d/n”, errno);
exit(EXIT_FAILURE);
}
/*向消息隊列中發送消息*/
while(running)
{
printf(“Enter some text: “);
fgets(buffer, BUFSIZ, stdin);
some_data.my_msg_type = 1;
strcpy(some_data.some_text, buffer);
if (msgsnd(msgid, (void *)some_data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, “msgsnd failed/n”);
exit(EXIT_FAILURE);
}
if (strncmp(buffer, “end”, 3) == 0)
{
running = 0;
}
}
exit(EXIT_SUCCESS);
}
receive.c
#include stdlib.h
#include stdio.h
#include string.h
#include errno.h
#include unistd.h
#include sys/types.h
#include sys/ipc.h
#include sys/msg.h
/*用於消息收發的結構體–my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running = 1;//程序運行標識符
int msgid; //消息隊列標識符
struct my_msg_st some_data;
long int msg_to_receive = 0;//接收消息的類型–0表示msgid隊列上的第一個消息
/*創建消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, “msgget failed with error: %d/n”, errno);
exit(EXIT_FAILURE);
}
/*接收消息*/
while(running)
{
if (msgrcv(msgid, (void *)some_data, BUFSIZ,msg_to_receive, 0) == -1)
{
fprintf(stderr, “msgrcv failed with error: %d/n”, errno);
exit(EXIT_FAILURE);
}
printf(“You wrote: %s”, some_data.some_text);
if (strncmp(some_data.some_text, “end”, 3) == 0)
{
running = 0;
}
}
/*刪除消息隊列*/
if (msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, “msgctl(IPC_RMID) failed/n”);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
③共享內存通信
share.h
#define TEXT_SZ 2048 //申請共享內存大小
struct shared_use_st
{
int written_by_you; //written_by_you為1時表示有數據寫入,為0時表示數據已經被消費者提走
char some_text[TEXT_SZ];
};
producer.c
#include unistd.h
#include stdlib.h
#include stdio.h
#include string.h
#include sys/types.h
#include sys/ipc.h
#include sys/shm.h
#include “share.h”
int main()
{
int running = 1; //程序運行標誌位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid; //共享內存標識符
/*創建共享內存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, “shmget failed/n”);
exit(EXIT_FAILURE);
}
/*將共享內存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個位元組的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, “shmat failed/n”);
exit(EXIT_FAILURE);
}
printf(“Memory attached at %X/n”, (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
/*生產者寫入數據*/
while(running)
{
while(shared_stuff-written_by_you == 1)
{
sleep(1);
printf(“waiting for client…/n”);
}
printf(“Enter some text: “);
fgets(buffer, BUFSIZ, stdin);
strncpy(shared_stuff-some_text, buffer, TEXT_SZ);
shared_stuff-written_by_you = 1;
if (strncmp(buffer, “end”, 3) == 0)
{
running = 0;
}
}
/*該函數用來將共享內存從當前進程中分離,僅使得當前進程不再能使用該共享內存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, “shmdt failed/n”);
exit(EXIT_FAILURE);
}
printf(“producer exit./n”);
exit(EXIT_SUCCESS);
}
customer.c
#include unistd.h
#include stdlib.h
#include stdio.h
#include string.h
#include sys/types.h
#include sys/ipc.h
#include sys/shm.h
#include “share.h”
int main()
{
int running = 1;//程序運行標誌位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid; //共享內存標識符
srand((unsigned int)getpid());
/*創建共享內存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, “shmget failed/n”);
exit(EXIT_FAILURE);
}
/*將共享內存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個位元組的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, “shmat failed/n”);
exit(EXIT_FAILURE);
}
printf(“Memory attached at %X/n”, (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
shared_stuff-written_by_you = 0;
/*消費者讀取數據*/
while(running)
{
if (shared_stuff-written_by_you)
{
printf(“You wrote: %s”, shared_stuff-some_text);
sleep( rand() % 4 );
shared_stuff-written_by_you = 0;
if (strncmp(shared_stuff-some_text, “end”, 3) == 0)
{
running = 0;
}
}
}
/*該函數用來將共享內存從當前進程中分離,僅使得當前進程不再能使用該共享內存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, “shmdt failed/n”);
exit(EXIT_FAILURE);
}
/*將共享內存刪除,所有進程均不能再訪問該共享內存*/
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf(stderr, “shmctl(IPC_RMID) failed/n”);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
摘自:
利用C語言寫一個程序實現兩個進程間進行管道通信
#include stdio.h
#include stdlib.h
#include errno.h
#include string.h
#define N 10
#define MAX 100
int child_read_pipe(int fd)
{
char buf[N];
int n = 0;
while(1)
{
n = read(fd,buf,sizeof(buf));
buf[n] = ‘\0’;
printf(“Read %d bytes : %s.\n”,n,buf);
if(strncmp(buf,”quit”,4) == 0)
break;
}
return 0;
}
int father_write_pipe(int fd)
{
char buf[MAX] = {0};
while(1)
{
printf(“”);
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1] = ‘\0’;
write(fd,buf,strlen(buf));
usleep(500);
if(strncmp(buf,”quit”,4) == 0)
break;
}
return 0;
}
int main()
{
int pid;
int fd[2];
if(pipe(fd) 0)
{
perror(“Fail to pipe”);
exit(EXIT_FAILURE);
}
if((pid = fork()) 0)
{
perror(“Fail to fork”);
exit(EXIT_FAILURE);
}else if(pid == 0){
close(fd[1]);
child_read_pipe(fd[0]);
}else{
close(fd[0]);
father_write_pipe(fd[1]);
}
exit(EXIT_SUCCESS);
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/245167.html