标签:ext space stdout semi shm val inf must ring
/*匿名管道*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main ()
{
int fd[2];
int ret;
pid_t pid;
if ( pipe(fd) == -1)
{
perror("pipe error");
return -1;
}
if ( ( pid = fork() ) == -1)
{
perror("fork error");
return -1;
}
if (pid > 0) //父进程
{
close(fd[0]); //关闭读端
char * str = "hello";
write(fd[1],str,strlen(str)+1);
close(fd[1]);
wait(NULL);
}
else if (pid == 0) //子进程
{
close(fd[1]);//关闭写端
char str[64] = {0};
ret = read(fd[0],str,sizeof(str));
write(STDOUT_FILENO,str,ret);
close(fd[0]);
}
return 0;
}
fifo_w.c
/*命名管道*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
int main ()
{
int key,ret;
int fd;
//判断文件是否存在
ret = access("fifo.tmp",F_OK);
if (ret == -1) //文件不存在,则创建
{
if (mkfifo("fifo.tmp",0664) == -1)
{
perror("mkfifo error");
exit(1);
}
else
{
printf("mkfifo sucess!\n");
}
}
fd = open("fifo.tmp",O_WRONLY);
while(1){
char *pt = "hello world !";
write (fd , pt ,strlen(pt)+1);
sleep(1);
}
close(fd);
return 0;
}
fifo_r.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
int fd ;
int ret ;
if ( access("fifo.tmp",F_OK) == -1)
{
printf("no exit file\n");
exit(1);
}
fd = open("fifo.tmp",O_RDONLY);
if(fd == -1)
{
perror ("open error");
return 1;
}
while(1)
{
char buf[64] = {0};
read(fd,buf,sizeof(buf));
printf("%s\n", buf);
}
close(fd);
return 0;
}
创建消息对象:
int msgget(key_t key, int msgflg);
msq_w.c
/*消息队列*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/msg.h>
#define MAX_TEXT 1024
//消息结构体
struct my_msg{
long int my_msg_type;//消息类型
char buf[MAX_TEXT];//消息数据
};
int main ()
{
int msqid;
struct my_msg data;
msqid = msgget((key_t)12345,0664|IPC_CREAT) ;//创建消息队列
if (msqid == -1)
{
perror("msgget error");
exit(-1);
}
int i = 0;
for (i = 0;i < 5;++i) //发五条消息
{
printf("please input: ");
fgets(data.buf,BUFSIZ,stdin);
data.my_msg_type = i+1;
//发送消息
if ( msgsnd(msqid,(void *)&data,sizeof(data.buf),0) == -1)
{
perror("msgsnd error");
exit(-1);
}
}
return 0;
}
msq_r.c
/*消息队列*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/msg.h>
#define MAX_TEXT 1024
struct my_msg
{
long int my_msg_type;
char buf[MAX_TEXT];
};
int main ()
{
int msqid;
struct my_msg data;
msqid = msgget( (key_t)12345,0664|IPC_CREAT);//获取消息队列
if (msqid == -1)
{
perror("msgget error");
exit(-1);
}
int i = 0;
for (i = 0;i < 5;++i) //收五条消息
{
//发送消息
if ( msgrcv(msqid,(void *)&data,BUFSIZ,i+1,0) == -1)
{
perror("msgrcv error");
exit(-1);
}
//打印
printf("rcv:%ld\n", data.my_msg_type);
printf("rcv:%s\n", data.buf);
}
//删除消息队列
if (msgctl(msqid,IPC_RMID,NULL) == -1)
{
perror("msgctl error");
exit(-1);
}
return 0;
}
struct semid_ds {
struct ipc_perm sem_perm; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Last change time */
unsigned long sem_nsems; /* No. of semaphores in set */信号量个数
struct sem * sem_base
};
struct sem{
int semval 信号量的值
int sempid 最近一个操作的进程号
}
创建对象:
int semget(key_t k,int n,int semflag);//key 个数 权限
设置对象:
int semctl(int sid,int semnum,int cmd,union semun a);
union semun {
int val; /* Value for SETVAL /
struct semid_ds buf; /* Buffer for IPC_STAT, IPC_SET /
unsigned short array; /* Array for GETALL, SETALL /
struct seminfo __buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
int semop(int s,struct sembuf *sb,size _t n);//操作信号量
struct sembuf
{
unsigned short int sem_num; //信号量的下标
short int sem_op; // 操作码 正数 表示增加信号的值
short int sem_flg;
};
sem_flg 操作标识 有两个取值IPC_NOWAIT 和 SEM_UNDO
IPC_NOWAIT 如果操作信号集合中任意一个失败,立即返回,并且不会对其他的信号量做操作,所以的信号量都不被操作
SEM_UNDO :进程退出后,该进程对sem进行的操作将被撤销
sem_w.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
//自定义联合体
union semu{
int val ;
struct semid_ds * buf;
unsigned short * array;
struct seminfo * _buf;
};
static int semid;
void init()
{
union semu sem_u;
key_t key;
key = ftok(".",0);
short arr[2];
arr[0] = 0; //生产出的产品数
arr[1] = 100; //仓库剩余容量
semid = semget(key,2,0664 | IPC_CREAT);
if (semid == -1)
{
perror("semget error");
exit(-1);
}
sem_u.array = arr;
if (semctl(semid,0,SETALL,sem_u) == -1 )
{
perror("semctl error");
exit(-1);
}
}
// p 操作 -1
int op_p(int num)
{
struct sembuf sem_p;
sem_p.sem_num = num;
sem_p.sem_op = -1;
sem_p.sem_flg = 0;
if (semop(semid,(struct sembuf *)&sem_p,1) == -1)
return 0;
return 1;
}
// v 操作 +1
int op_v(int num)
{
struct sembuf sem_v;
sem_v.sem_num = num;
sem_v.sem_op = 1;
sem_v.sem_flg = 0;
if (semop(semid,(struct sembuf *)&sem_v,1) == -1)
return 0;
return 1;
}
int main ()
{
init();
while(1)
{
printf("before\n");
printf("productor number is %d\n",semctl(semid,0,GETVAL));
printf("space number is %d\n",semctl(semid,1,GETVAL));
op_p(1);//写一个,那么仓库容量减1 (如果容量不足将阻塞等待)
printf("生产了一件商品\n");
op_v(0);//产品数目增加1 (即通知消费者可以消耗商品)
printf("before\n");
printf("productor number is %d\n",semctl(semid,0,GETVAL));
printf("space number is %d\n",semctl(semid,1,GETVAL));
sleep(4);
}
//删除信号量
semctl(semid,IPC_RMID,0);
return 0;
}
sem_r.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
static int semid;
void init()
{
key_t key;
key = ftok(".",0);
semid = semget(key,2,0664 | IPC_CREAT);
if (semid == -1)
{
perror("semget error");
exit(-1);
}
}
// p 操作 -1
int op_p(int num)
{
struct sembuf sem_p;
sem_p.sem_num = num;
sem_p.sem_op = -1;
sem_p.sem_flg = 0;
if (semop(semid,(struct sembuf *)&sem_p,1) == -1)
return 0;
return 1;
}
// v 操作 +1
int op_v(int num)
{
struct sembuf sem_v;
sem_v.sem_num = num;
sem_v.sem_op = 1;
sem_v.sem_flg = 0;
if (semop(semid,(struct sembuf *)&sem_v,1) == -1)
return 0;
return 1;
}
int main ()
{
init();
while(1)
{ printf("before\n");
printf("productor number is %d\n",semctl(semid,0,GETVAL));
printf("space number is %d\n",semctl(semid,1,GETVAL));
//编号 0 是商品数目 1 是库存
op_p(0);//消费一个,那么商品数目减一(如果商品数不足将阻塞等待)
printf("消费了一件商品\n");
op_v(1);//库存容量增加1
printf("after \n");
printf("productor number is %d\n",semctl(semid,0,GETVAL));
printf("space number is %d\n",semctl(semid,1,GETVAL));
sleep(3);
}
return 0;
}
struct shmid_ds
struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */
__kernel_time_t shm_atime; /* last attach time */
__kernel_time_t shm_dtime; /* last detach time */
__kernel_time_t shm_ctime; /* last change time */
__kernel_ipc_pid_t shm_cpid; /* pid of creator */
__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
unsigned short shm_nattch; /* no. of current attaches */
unsigned short shm_unused; /* compatibility */
void *shm_unused2; /* ditto - used by DIPC */
void *shm_unused3; /* unused */
};
int shmget (key_t key, size_t size, int shmflg) ;
int shmctl (int shmid, int cmd, struct shmid_ds *buf) ;
特殊 cmd:
SHM_INFO
SHM_STAT
SHM_LOCK
SHM_UNLOCK
void shmat (int shmid, const void shmaddr, int shmflg);//将进程与共享内存绑定
int shmdt (const void * shmaddr); //解除绑定
// shmaddr 填NULL ,由内核帮助你来分配
SHM_RDONLY //只读
SHM_REMAP //重新映射
SHM_EXEC //可读可写
0 //可读可写
1.父子进程的共享内存约定
fork函数 子进程会继承共享内存
exec执行一个新的程序 自动卸载
共享内存用完了记得shmdt();
信号量 和 共享内存的连用,信号通知,然后从共享内存中读
shm_w.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#define SEGSIZE 680
/*对于共享内存,获得内存地址后,更具你要传递的数据的类型
该指针进行类型转换即可,这样很方便完成数据的传递,非常不错的IPC方式*/
typedef struct data
{
char name[64];
int age ;
}Sdat;
int main(int argc, char const *argv[])
{
key_t key;
int shm_id;
Sdat * smap = NULL;
key = ftok(".",2);
//创建共享内存
shm_id = shmget(key,SEGSIZE,IPC_CREAT | 0664);
if (shm_id == -1)
{
perror("shmget error");
return 1;
}
//将进程与共享内存绑定,映射
smap =(struct data*)shmat(shm_id,NULL,0);
char buf[64] = "john";
int i = 0;
for (i = 0;i < 10 ; ++i) //往共享内存中写东西
{
strcpy((smap+i)->name,buf);
(smap+i)->age = i*10;
}
if (shmdt(smap) == -1)
{
perror("shmdt error");
return -1;
}
return 0;
}
shm_r.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#define SEGSIZE 680 //刚好10个结构体大小
/*对于共享内存,获得内存地址后,更具你要传递的数据的类型
该指针进行类型转换即可,这样很方便完成数据的传递,非常不错的IPC方式*/
typedef struct data
{
char name[64];
int age ;
}Sdat;
int main(int argc, char const *argv[])
{
key_t key;
int shm_id;
Sdat * smap = NULL;
key = ftok(".",2);
//创建共享内存
shm_id = shmget(key,SEGSIZE,IPC_CREAT | 0664);
if (shm_id == -1)
{
perror("shmget error");
return 1;
}
//将进程与共享内存绑定,映射
smap =(struct data*)shmat(shm_id,NULL,0);
int i = 0;
for (i = 0;i < 10 ; ++i) //从共享内存中读东西
{
printf("%s\n",(smap+i)->name );
printf("%d\n",(smap+i)->age );
}
if (shmdt(smap) == -1)
{
perror("shmdt error");
return -1;
}
if ( -1== shmctl(shm_id,IPC_RMID,0) )
{
perror("shmctl error");
return -1;
}
return 0;
}
标签:ext space stdout semi shm val inf must ring
原文地址:https://www.cnblogs.com/yuluoluo/p/9084533.html