進程間通訊方式一般有共享內存 信號量 消息隊列 管道 FIFO Socket等幾種。 多線程
共享內存(分配 綁定 脫離 釋放)異步
1:效率高,特別是大數據量通訊post
2:各進程須要協調共同的鍵值,須要提供額外機制防止競爭條件大數據
3:異步通訊線程
4:和信號量一同使用隊列
內存映射(多進程共享文件進行通訊的機制)進程
1:分配內存ip
2:讀入文件內容至內存內存
3:內存的內容回寫到文件get
信號量
1:線程信號量:同步多線程環境的計數器。
2:進程間同步的信號量: System V信號量,操做和sharedmemory相似。
消息隊列
1打開或建立消息隊列
2讀寫操做
3得到或設置隊列屬性
管道
1:單向信息的傳遞設備
2:用於進程的線程之間或者是父子進程之間通訊
3:自動同步進程(管道的容量是有限的當管道寫滿的時候,寫入端自動阻塞管道容量4096字節)
FIFO
1:在文件系統中是一個有名字的管道
2:任何進程均可以打開
3:進程間無需關聯
SocketSocket
1:是一種雙向通訊設備
2:同一主機不一樣進程間通訊
3:不一樣主機間的通訊
如下是一些程序,幫助你們理解
共享內存
#include"stdio.h"
#include"sys/shm.h"
#include"string.h"
#include"fcntl.h"
#include"sys/stat.h"
int main()
{
pid_t pid;
int share_id;
share_id=shmget(IPC_PRIVATE,getpagesize(),IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR );
pid=fork();
if(pid==0)
{
char *share1=NULL;
share1=(char*) shmat (share_id, 0,0);
memset(share1,0,getpagesize());
strcpy(share1,"hello,everyone\n");
shmdt(share1);
}
else if(pid>0)
{
char *share2=NULL;
share2=(char*) shmat(share_id,0,0);
printf("read characters from memory!\n");
printf("%s\n",share2);
shmdt(share2);
shmctl(share_id,IPC_RMID,0);
}
return 1;
}
信號量
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#define MAX 3
union semun
{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *_buf;
};
int sig_alloc(key_t key, int sem_flags)
{
return semget (key, MAX, sem_flags);
}
int sig_destory (int semid,int numth)
{
union semun ignored_argument;
return semctl (semid, numth, IPC_RMID,ignored_argument);
}
/*
parray is a set of initialized value
*/
int sig_init (int semid,int *parray)
{
union semun argument;
int i=0;
for(i=0;i<MAX;i++)
{
// values[i] = *(parray+i);
argument.array = parray;
semctl (semid, i, SETALL, argument);
}
}
int sig_wait(int semid,int numth)
{
struct sembuf operations[MAX];
operations[numth-1].sem_num = numth-1;
operations[numth-1].sem_op = -1;
operations[numth-1].sem_flg = SEM_UNDO;
return semop(semid,operations,1);
}
int sig_post(int semid,int numth)
{
struct sembuf operations[MAX];
operations[numth-1].sem_num = numth-1;
operations[numth-1].sem_op = 1;
operations[numth-1].sem_flg = SEM_UNDO;
return semop(semid,operations,1);
}
int main()
{
pid_t pid;
int sig_id,i=0;
int sig_val[MAX]={1,0,0};
sig_id=sig_alloc(0,IPC_CREAT);
sig_init(sig_id,sig_val);
pid=fork();
if(pid==0)
{
while(++i<10)
{
sig_wait(sig_id,3);
printf("*************** \n");
sig_post(sig_id,3);
}
}
else if(pid)
{
i=0;
while(++i<10)
{
sig_wait(sig_id,1);
printf("++++++++++++++++\n");
sig_post(sig_id,1);
}
}
return 1;
}
內存映射
#include <sys/mman.h>
#include <sys/types.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#define FILE_LENGTH 100
int main(int argc,char **argv)
{
int fd1,fd2;
char *pfile=NULL;
char *load=NULL;
int num;
if(argc<3)
{
printf("please input more file\n");
return 0;
}
fd1=open(argv[1],O_RDONLY);
fd2=open(argv[2],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);
printf("fd2=%d\n",fd2);
//fd2=open(argv[2],O_WRONLY);
lseek (fd2, FILE_LENGTH+1, SEEK_SET);
write (fd2, "", 1);
lseek (fd2, 0, SEEK_SET);
printf("num=%d\n",num);
printf("fd2=%d\n",fd2);
pfile=(char*)mmap(0,FILE_LENGTH,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd2,0);
read(fd1,pfile,FILE_LENGTH);
write(fd2,pfile,FILE_LENGTH);
close(fd2);
printf("pfile=%d\n",pfile);
munmap(pfile,FILE_LENGTH);
close(fd1);
return 1;
}
管道
#include <sys/mman.h>
#include <sys/types.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
int main ()
{
int fds[2];
pid_t pid;
pipe (fds);
pid = fork ();
if (pid == (pid_t) 0)
{
char str[10000];
sleep(1);
close(fds[1]);
read(fds[0],str,10000);
printf("%s",str);
close(fds[0]);
}
else if(pid>0)
{
FILE*fp;
char a[80];
close(fds[0]);
fp=(fopen("copy1.c","r"));
if(fp==NULL)
{
printf("can not open!!");
exit(0);
}
else
{
while(1)
{
if(fread(a,80,1,fp)==0) break;
write(fds[1],a,sizeof(a));
}
}
wait();
close(fds[1]);
fclose(fp);
return 0;
}