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 (信號量)使用的章節。