IPC的三大点
1.信号量(SYSTEM V IPC)与线程的信号量完全不同
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
static int set_semvalue(void);
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);
static int sem_id;
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int main(int argc,char *argv[]){
int i;
int pause_time;
char op_char='O';
srand((unsigned int)getpid());
sem_id=semget((key_t)1234,1,0666|IPC_CREAT);
if(argc>1){
if(!set_semvalue()){///把信号量设为1
fprintf(stderr,"failed to initialize semaphore");
exit(1);
}
op_char ='X';
sleep(2);
}
for(i=0;i<10;i++){
if(!semaphore_p())exit(1);
printf("%c",op_char);fflush(stdout);
pause_time=rand()%3;
sleep(pause_time);
printf("%c",op_char);fflush(stdout);
if(!semaphore_v())exit(1);
pause_time=rand()%2;
sleep(pause_time);
}
printf("\n%d-finished\n",getpid());
if(argc>1){
sleep(10);
del_semvalue();
}
exit(0);
}
static int set_semvalue(void){
union semun sem_union;
sem_union.val=1;
if(semctl(sem_id,0,SETVAL,sem_union)==-1)return(0);
return(1);
}
static void del_semvalue(void){
union semun sem_union;
if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)fprintf(stderr,"failed to delete semaphore\n");
}
static int semaphore_p(void){
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=-1;
sem_b.sem_flg=SEM_UNDO;
if(semop(sem_id,&sem_b,1)==-1){
fprintf(stderr,"semaphore_p failed");
return(0);
}
return(1);
}
static int semaphore_v(void){
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=1;
sem_b.sem_flg=SEM_UNDO;
if(semop(sem_id,&sem_b,1)==-1){
fprintf(stderr,"failed semaphore_v");
return(0);
}
return(1);
}
2.共享内存
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<string.h>
#include<sys/shm.h>
#define TEXT_SZ 2048
struct shared_use_st{
int written_by_you;
char some_text[TEXT_SZ];
};
int main(){
char buffer[BUFSIZ];
int running=1;
void *shared_memory=(void *)0;
struct shared_use_st *shared_stuff;
int shmid;
srand((unsigned int)getpid());
shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
if(shmid==-1){
fprintf(stderr,"failed initialzation of shared memory");
exit(1);
}
shared_memory=shmat(shmid,(void *)0,0);///把选则共享内存的地址的工作交给系统
if(shared_memory==(void *)-1){
fprintf(stderr,"shmat failed");
exit(1);
}
printf("memory attached at %X\n",(int)shared_memory);
shared_stuff=(struct shared_use_st *)shared_memory;
while(running){
while(shared_stuff->written_by_you==1){
sleep(1);
printf("waiting for client\n");
}
printf("enter someting\n");
fgets(buffer,BUFSIZ,stdin);
strncpy(shared_stuff->some_text,buffer,TEXT_SZ);
shared_stuff->written_by_you=1;
if(strncmp(buffer,"end",3)==0)running=0;
}
if(shmdt(shared_memory)==-1){
fprintf(stderr,"shmdt failed");
exit(1);
}
exit(0);
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<string.h>
#include<sys/shm.h>
#define TEXT_SZ 2048
struct shared_use_st{
int written_by_you;
char some_text[TEXT_SZ];
};
int main(){
int running=1;
void *shared_memory=(void *)0;
struct shared_use_st *shared_stuff;
int shmid;
srand((unsigned int)getpid());
shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
if(shmid==-1){
fprintf(stderr,"failed initialzation of shared memory");
exit(1);
}
shared_memory=shmat(shmid,(void *)0,0);///把选则共享内存的地址的工作交给系统
if(shared_memory==(void *)-1){
fprintf(stderr,"shmat failed");
exit(1);
}
printf("memory attached at %X\n",(int)shared_memory);
shared_stuff=(struct shared_use_st *)shared_memory;
shared_stuff->written_by_you=0;
while(running){
if(shared_stuff->written_by_you){
printf("you wrote %s\n",shared_stuff->some_text);
sleep(rand()%4);
shared_stuff->written_by_you=0;
if(strncmp(shared_stuff->some_text,"end",3)==0)
running=0;
}
}
if(shmdt(shared_memory)==-1){
fprintf(stderr,"shmdt failed");
exit(1);
}
if(shmctl(shmid,IPC_RMID,0)==-1){
fprintf(stderr,"remove shmid failed");
exit(1);
}
exit(0);
}
3.消息队列(基本避免了FIFO的同步和阻塞问题
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<string.h>
#include<sys/msg.h>
#define MAX_TEXT 512
struct my_msg_st{
long int my_msg_type;
char some_text[MAX_TEXT];
};
int main(){
int running=1;
char buffer[BUFSIZ];
int msgid;
struct my_msg_st some_data;
//long int msg_to_receive=0;
msgid=msgget((key_t)1234,0666|IPC_CREAT);
if(msgid==-1){
fprintf(stderr,"msg get failed");
exit(1);
}
while(running){
printf("enter something\n");
fgets(buffer,BUFSIZ,stdin);
some_data.my_msg_type=1;
strcpy(some_data.some_text,buffer);
if(msgsnd(msgid,(void *)&some_data,MAX_TEXT,0)==-1){
fprintf(stderr,"snd failed");
exit(1);
}
printf("you wrote: %s",some_data.some_text);
if(strncmp(buffer,"end",3)==0)running=0;
}
exit(0);
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<string.h>
#include<sys/msg.h>
struct my_msg_st{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main(){
int running=1;
int msgid;
struct my_msg_st some_data;
long int msg_to_receive=0;//优先级设定,若为0,则提取第一个消息
msgid=msgget((key_t)1234,0666|IPC_CREAT);
if(msgid==-1){
fprintf(stderr,"msg get failed");
exit(1);
}
while(running){
if(msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_receive,0)==-1){
fprintf(stderr,"rcv failed");
exit(1);
}
printf("you wrote: %s",some_data.some_text);
if(strncmp(some_data.some_text,"end",3)==0)running=0;
}
if(msgctl(msgid,IPC_RMID,0)==-1){
fprintf(stderr,"remove failed");
exit(1);
}
exit(0);
}
没有评论:
发表评论