???? 進程間通信方式通常有共享內存 信號量 消息隊列 管道 FIFO Socket等幾種。??
????????????? 共享內存(分配 綁定 脫離 釋放)
1:效率高,特別是大數據量通信
2:各進程需要協調共同的鍵值,需要提供額外機制防止競爭條件
3:異步通信
4:和信號量一同使用
?????????????????? 內存映射(多進程共享文件進行通信的機制)
?????????????????? 1:分配內存
???????????????????2:讀入文件內容至內存
?????????????????? 3:內存的內容回寫到文件
????????????? 信號量
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;
??? }