本文目录一览:
- 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);
}