Chinaunix首页 | 论坛 | 博客
  • 博客访问: 39193
  • 博文数量: 41
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 357
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-20 16:26
文章分类

全部博文(41)

文章存档

2014年(41)

我的朋友

分类: LINUX

2014-05-09 23:47:37

linux进程间通信主要有以下几种:
1.共享内存与信号量
两个进程间使用共享内存达到数据共享,通常需要使用信号量进行同步。
使用共享内存的步骤:
获取关键字:通常使用ftok函数,根据不同的文件名和id获取关键字,只要文件名和id都一样,不同程序获得的关键字就相同。
key_t ftok(const char *pathname, int proj_id);

创建:int shmget(key_t key, size_t size, int shmflg);
key:由ftok获得的关键字
size:共享内存大小
shmflg:IPC_CREAT and IPC_EXCL

绑定:void *shmat(int shmid, const void *shmaddr, int shmflg);
将id为shmid的共享内存绑定到返回的地址
id:标识每一个共享内存
shmaddr:指定要绑定的地址,通常设为0,表示系统自动分配
shmflg:读写权限,一般为0,表示可读可写
绑定了之后就可以使用

脱离:int shmdt(const void *shmaddr);
将共享内存从程序空间脱离

销毁:int shmctl(int shmid, int cmd, struct shmid_ds *buf);
根据cmd的不同,可获得共享内存的信息,删除共享内存等
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16 #include
 17 #include
 18
 19 struct mymsg
 20 {
 21     int type;
 22     char msg[1020];
 23 };
 24 int shmid;
 25 int semid;
 26 struct mymsg *addr = NULL;
 27 void sig_int(int sig);
 28 void *read_shm(void *arg);
 29 void semp();
 30 void semv();
 31
 32 int main()
 33 {
 34     int ret;
 35 //  char buf[1024];
 36     key_t key;
 37     if((key = ftok(".", 1)) == -1)
 38     {
 39         perror("ftok");
 40         exit(1);
 41     }
 42
 43     shmid = shmget(key, 1024, IPC_CREAT | IPC_EXCL | 0777);
 44     if(shmid == -1)
 45     {
 46         if(errno == EEXIST)
 47             shmid = shmget(key, 1024, 0);
 48         if(shmid == -1)
 49         {
 50             perror("shmget");
 51             exit(1);
 52         }
 53     }
 54     if((addr = shmat(shmid, 0, 0)) == NULL)
 55     {
 56         perror("shmat");
 57         exit(1);
 58     }
 59     printf("%d %p\n", shmid, addr);
 60
 61     if((semid = semget(key, 2, IPC_CREAT | IPC_EXCL)) == -1)
 62     {
 63         if(errno == EEXIST)
 64             semid = semget(key, 1, 0);
 65         if(semid == -1)
 66         {
 67             perror("semget");
 68             exit(1);
 69         }
 70     }
 71     else
 72     {
 73         if(semctl(semid, 0, SETVAL, 1) == -1)
 74         {
 75             perror("semctl");
 76             exit(1);
 77         }
 78         if(semctl(semid, 1, SETVAL, 1) == -1)
 79         {
 80             perror("semctl");
 81             exit(1);
 82         }
 83     }
 84
 85     memset(addr, 0, 1024);
 86     signal(SIGINT, sig_int);
 87     pthread_t tid;
 88     if(pthread_create(&tid, NULL, read_shm, NULL) == -1)
 89     {
 90         perror("pthread_create");
 91         exit(1);
 92     }
 93     pthread_detach(tid);
 94
 95     while(1)
 96     {
 97     // 
 98     //  printf
 99         ret = read(0, addr->msg, 1020);
100         if(ret == -1)
101         {
102             perror("read");
103             continue;
104         }
105         addr->msg[ret] = '\0';
106         addr->type = 2;
107         semv(0);
108     }
109
110     return 0;
111 }
112
113 void semp(int p)
114 {
115     struct sembuf sops = { p, -1, 0};
116     if(semop(semi, &sops, 1) == -1)
117     {
118         if(errno == 22)
119             exit(0);
120         perror("semop_semp");
121         exit(1);
122     }
123 }
124 void semv(int p)
125 {
126     struct sembuf sops = { p, 1, 0};
127     if(semop(semid, &sops, 1) == -1)
128     {
129         if(errno == 22)
130             exit(0);
131         perror("semop_semv");
132         exit(1);
133     }
134 }
135
136 void *read_shm(void *arg)
137 {
138     while(1)
139     {
140         semp(1);
141         if(addr->type == 1)
142         {
143             printf("miki:%s", addr->msg);
144             addr->type = 0;
145             memset(addr, 0, 1024);
146         }
147         //sleep(1);//printf("isisisisis\n");
148     }
149 }
150
151 void sig_int(int sig)
152 {
153     if(shmdt(addr) == -1)
154     {
155         perror("shmdt");
156         exit(1);
157     }
158
159     if(shmctl(shmid, IPC_RMID, NULL) == -1)
160     {
161         perror("shmctl");
162         exit(1);
163     }
164
165     if(semctl(semid, 0, IPC_RMID) == -1)
166     {
167         perror("semctl");
168         exit(1);
169     }
170
171     exit(0);
172 }

阅读(218) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~