1、LINUX 信号量共存 共享内存通信
|/***Msginput.c***/
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include"Mysem.h"
int main(){
FILE *fp;
int empty;
int full;
int mutex;
char * shm;
int shmid;
fp = fopen("shmid","r");
fread(&shmid,sizeof(int), 1, fp);
fread(&empty,sizeof(int), 1, fp);
fread(&full,sizeof(int), 1, fp);
fread(&mutex,sizeof(int), 1, fp);
fclose(fp);
shm = shmat(shmid, NULL, 0);
while(1){
P(&empty);
P(&mutex);
scanf("%s", shm);
if(strcmp(shm, "END") == 0){
V(&mutex);
V(&full);
break;
}
V(&mutex);
V(&full);
}
return 0;
}
/****Mysem.c*****/
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include "Mysem.h"
#define BUFFER_SIZE 512
int main(){
char *shm;
int empty;
int full;
int mutex;
int shmid;
int pid;
int i;
FILE *fp;
// int init_sem_value = 0;
empty = semget(IPC_PRIVATE, 1, (0600|_CREAT));
if(empty == -1){
perror("semget");
exit(1);
}
if(semctl(empty, 0, SETVAL, 1)<0){
perror("semctl");
exit(1);
}
full = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));
if(full == -1){
perror("semget");
exit(1);
}
if(semctl(full, 0, SETVAL, 0)<0){
perror("semctl");
exit(1);
}
mutex = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));
if(mutex == -1){
perror("semget");
exit(1);
}
if(semctl(mutex, 0, SETVAL, 1)<0){
perror("semctl");
exit(1);
}
shmid = shmget(IPC_PRIVATE, (BUFFER_SIZE*sizeof(char)),(IPC_CREAT|0600));
if(shmid == -1){
perror("shmget");
exit(1);
}
shm = shmat(shmid, NULL, 0);
if(shm == (char*)-1){
perror("shmat");
exit(1);
}
fp = fopen("shmid","w");
fwrite(&shmid, sizeof(int), 1, fp);
fwrite(&empty, sizeof(int), 1, fp);
fwrite(&full, sizeof(int), 1, fp);
fwrite(&mutex, sizeof(int), 1, fp);
fclose(fp);
pid = fork();
if(pid == 0){
execlp("./Msginput", "./Msginput",0);
perror("execlp");
exit(1);
}else{
while(1){
P(&full);
P(&mutex);
printf("%s\n", shm);
if(strcmp(shm,"END") == 0){
V(&mutex);
V(&empty);
break;
}
V(&mutex);
V(&empty);
}
}
wait(0);
if(semctl(full, 0, IPC_RMID, 1) == -1){
perror("semctl");
exit(1);
}
if(semctl(empty, 0, IPC_RMID, 1) == -1){
perror("semctl");
exit(1);
}
if(semctl(mutex, 0, IPC_RMID, 1) == -1){
perror("semctl");
exit(1);
}
if(shmctl(shmid, IPC_RMID, NULL) == -1){
perror("shmctl");
exit(1);
}
exit(0);
}
/****Mysem.h*****/
void P(int *s);
void V(int *s);
extern void *shmat (int __shmid, __const void *__shmaddr, int __shmflg);
void P(int *s){
struct sembuf sembuffer, *sops;
sops=&sembuffer;
sops->sem_num = 0;
sops->sem_op = -1;
sops->sem_flg = 0;
if(semop(*s, sops, 1)<0){
perror("semop");
exit(1);
}
return ;
}
void V(int *s){
struct sembuf sembuffer, *sops;
sops = &sembuffer;
sops->sem_num = 0;
sops->sem_op = 1;
sops->sem_flg = 0;
if(semop(*s, sops, 1)<0){
perror("semop");
exit(1);
}
return;
}
2、linux进程间通信问题 我想用共享内存的方式实现信号量控制一个不许并行的的函数 请问下面我的代码合理吗
我想你的目的是有一段代码 (即你标的 /*..........只能单独进行的函数.........*/)
在任意时刻最多只能有最多一个进程执行,是吧。
首先,你的做法是错的…… 简单的说,原因是由于
while( *shmaddr );
*shmaddr = 1;
这两行代码不是一个原子操作,从while判断出 *shmaddr等于0 到 *shmaddr=1 之间,另外一个或多个进程可能也会得到 *shmaddr==0 的判断,从而导致多个进程同时进入 /*..........只能单独进行的函数.........*/
具体关于互斥的基本原理,以及你为什么错,可以找一本讲操作系统原理 (关于进程同步的内容)去看。
所以,用 shared memory 来实现进程同步肯定是不行的,正确的做法是使用 semaphore, 具体可以参考 《unix 环境高级编程》中关于 semaphore (信号量)使用的章节。