pipe函数; fd【0】读;fd【1】写
无名管道:有血缘关系的进程,比如父子进程,管道也属于文件;
例句:ret =pipe(fd); //创建无名管道
pid =fork(); //先创建管道,再创建子进程。
else if (0 == pid) //子进程
{
close(fd[0]);
a++;
ret = write(fd[1], &a, sizeof(int)); //数据a写入管道
if (-1 == ret)
{
perror(“write”);
exit(1);
}
printf(“Child a = %d\n”, a);
}
ret = read(fd[0], &a, sizeof(int)); //从管道读数据
if (-1 == ret)
{
perror(“read”);
exit(1);
}
a++;
printf(“Parent a = %d\n”, a);
**
mkfifo:有名管道。
**
例句:ret = mkfifo(“fifo.tmp”, 00700); //创建有名管道文件
fd = open(“fifo.tmp”, O_RDONLY); //只读方式打开管道文件
unlink(“fifo.tmp”); //删除管道文件
fd = open(“fifo.tmp”, O_WRONLY); //只写的方式打开管道文件
消息队列
1.创建消息队列(获取)
msgget();
2.读写消息队列
msgsnd(); msgrcv();
3删除消息队列
msgctl();
关于消息队列的代码:
文件1中;
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#define MSGKEY 1234
struct msgbuf {
long mtype; /* message type, must be > 0 /
char mtext[100]; / message data */
};
int main()
{
int ret;
int msgid;
struct msgbuf m;
pid_t pid;
msgid = msgget(MSGKEY, IPC_CREAT | IPC_EXCL); //创建消息队列
if (-1 == msgid)
{
perror("msgget");
exit(1);
}
pid = fork();
if (-1 == pid)
{
perror("fork");
exit(1);
}
else if (0 == pid) //子进程发送数据
{
while (1)
{
memset(&m, 0, sizeof(m));
scanf("%s", m.mtext);
m.mtype = 1;
ret = msgsnd(msgid, &m, sizeof(m.mtext), 0);
if (-1 == ret)
{
perror("msgsnd");
}
if (!strcmp(m.mtext, "bye"))
{
m.mtype = 2;
ret = msgsnd(msgid, &m, sizeof(m.mtext), 0);
if (-1 == ret)
{
perror("msgsnd");
}
break;
}
}
}
else //父进程接收数据
{
while (1)
{
ret = msgrcv(msgid, &m, sizeof(m.mtext), 2, 0); //接收消息类型为2
if (-1 == ret)
{
perror("msgrcv");
}
if (!strcmp(m.mtext, "bye"))
{
kill(pid, SIGINT);
break;
}
printf("\t\t%s\n", m.mtext);
memset(&m, 0, sizeof(m));
}
sleep(1);
msgctl(msgid, IPC_RMID, NULL); //删除消息队列
}
return 0;
}
文件2中:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#define MSGKEY 1234
struct msgbuf {
long mtype; /* message type, must be > 0 /
char mtext[100]; / message data */
};
int main()
{
int msgid, ret;
struct msgbuf m;
msgid = msgget(MSGKEY, 0); //获取消息队列
if (-1 == msgid)
{
perror("msgget");
exit(1);
}
pid_t pid = fork();
if (-1 == pid)
{
perror("fork");
exit(1);
}
else if (0 == pid) //子进程发送数据
{
while (1)
{
scanf("%s", m.mtext);
m.mtype = 2; //发送的消息类型为2
ret = msgsnd(msgid, &m, sizeof(m.mtext), 0);
if (-1 == ret)
{
perror("msgsnd");
}
if (!strcmp(m.mtext, "bye"))
{
m.mtype = 1;
msgsnd(msgid, &m, sizeof(m.mtext), 0);
break;
}
memset(&m, 0, sizeof(m));
}
}
else //父进程接收数据
{
while (1)
{
memset(&m, 0, sizeof(m));
ret = msgrcv(msgid, &m, sizeof(m.mtext), 1, 0);
if (-1 == ret)
{
perror("msgrcv");
}
if (!strcmp(m.mtext, "bye"))
{
kill(pid, SIGINT);
break;
}
printf("\t\t%s\n", m.mtext);
}
}
return 0;
}
关于共享内存:
步骤:
1.创建(获取)共享内存
shmget();
2.映射
shmat();
3.使用共享内存
4.解除映射
shmat();
5删除共享内存
shmct();
代码部分:
文件1;
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SHMKEY 1234
#define SHMSIZE 4096 //以页为单位分配
#define SEMKEY 1234
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) */
};
void sem_p(int id)
{
struct sembuf s;
s.sem_num = 0; //第0个信号量
s.sem_op = -1; //减一操作
s.sem_flg = SEM_UNDO; //如果进程出现异常退出,信号量恢复初始值
int ret = semop(id, &s, 1); //p操作
if (-1 == ret)
{
perror(“semop”);
}
}
void sem_v(int id)
{
struct sembuf s;
s.sem_num = 0; //第0个信号量
s.sem_op = 1; //加一操作
s.sem_flg = SEM_UNDO; //如果进程出现异常退出,信号量恢复初始值
int ret = semop(id, &s, 1); //p操作
if (-1 == ret)
{
perror(“semop”);
}
}
int main()
{
int shmid, ret;
void *shmaddr;
int count = 100;
shmid = shmget(SHMKEY, SHMSIZE, IPC_CREAT | IPC_EXCL); //创建共享内存
if (-1 == shmid)
{
perror("shmget");
exit(1);
}
int semid = semget(SEMKEY, 1, IPC_CREAT | IPC_EXCL); //创建信号量(1个)
if (-1 == semid)
{
perror("semget");
exit(1);
}
union semun s;
s.val = 1; //二值信号量
ret = semctl(semid, 0, SETVAL, s); //初始化信号量
if (-1 == ret)
{
perror("semctl");
exit(1);
}
shmaddr = shmat(shmid, NULL, 0); //共享内存映射,返回映射后的地址(虚拟内存的地址)
if (NULL == shmaddr)
{
perror("shmat");
exit(1);
}
*(int *)shmaddr = count; //把共享数据写入共享内存
while (1)
{
sem_p(semid); //减一操作
count = *(int *)shmaddr; //获取数据
if (count < 0)
{
sem_v(semid);
break;
}
printf("%d count = %d\n", getpid(), count);
count--;
usleep(10000);
*(int *)shmaddr = count; //数据写回共享内存
sem_v(semid); //加一操作
}
shmdt(shmaddr); //解除映射
sleep(1);
shmctl(shmid, IPC_RMID, NULL); //删除共享内存
semctl(semid, 0, IPC_RMID); //删除信号量
return 0;
}
文件2:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SHMKEY 1234
#define SHMSIZE 4096 //以页为单位分配
#define SEMKEY 1234
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) */
};
void sem_p(int id)
{
struct sembuf s;
s.sem_num = 0; //第0个信号量
s.sem_op = -1; //减一操作
s.sem_flg = SEM_UNDO; //如果进程出现异常退出,信号量恢复初始值
int ret = semop(id, &s, 1); //p操作
if (-1 == ret)
{
perror(“semop”);
}
}
void sem_v(int id)
{
struct sembuf s;
s.sem_num = 0; //第0个信号量
s.sem_op = 1; //加一操作
s.sem_flg = SEM_UNDO; //如果进程出现异常退出,信号量恢复初始值
int ret = semop(id, &s, 1); //p操作
if (-1 == ret)
{
perror(“semop”);
}
}
int main()
{
int shmid, ret;
void *shmaddr;
int count = 100;
shmid = shmget(SHMKEY, SHMSIZE, 0); //获取共享内存
if (-1 == shmid)
{
perror("shmget");
exit(1);
}
int semid = semget(SEMKEY, 1, 0); //获取信号量(1个)
if (-1 == semid)
{
perror("semget");
exit(1);
}
shmaddr = shmat(shmid, NULL, 0); //共享内存映射,返回映射后的地址(虚拟内存的地址)
if (NULL == shmaddr)
{
perror("shmat");
exit(1);
}
while (1)
{
sem_p(semid); //减一操作
count = *(int *)shmaddr; //获取数据
if (count < 0)
{
sem_v(semid);
break;
}
printf("%d count = %d\n", getpid(), count);
count--;
usleep(10000);
*(int *)shmaddr = count; //数据写回共享内存
sem_v(semid); //加一操作
}
shmdt(shmaddr); //解除映射
return 0;
}
**关于信号量的知识:
1.创建信号量
semget();
2.初始化信号量
semctl();
3.pv操作
semop();
4。删除信号量
semctl();
代码部分: