进程
至于一些进程线程的概念就不说了,一个helloword 就是一进程一线程
如果理解不了有个故事就是,cpu是爷爷,进程是father,瓜分了cpu资源,去培养cpu的孙子,所以实际操作资源的是他们的孙子,而由于父亲是多胞胎,大家同时出生导致等级规则相同,分到了同样的东西,然后有一个歪风邪气的东西“线程优先级”,就是“嫡孙子继承制” ,而因为“嫡孙子继承制” 不是明面上的东西,所以需要大家自己去了解
而因为他们father划清某些“界限”,“文件地盘”不一样,导致有些“种子变量”不能分享,进而孙子直接得自己搭建一些“桥梁”去联系他们的兄弟以及他们的老表以及就有了下面的通信方式,懂了吧
一 管道
1.无名管道
其是有血缘关系之间的通信,比如父子进程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*使用匿名管道实现进程间通信*/
int main()
{
int fd[2];//fd[0]为读端 fd[1]为写端
pid_t pid;
char buff[20];
char buf[128];
int i=0;
//int pipe(int pipefd[2]);
if(pipe(fd) == -1)//创建管道
{
printf("管道创建失败\n");
perror("why");
}
pid = fork();
if(pid < 0 )
{
printf("子进程开辟失败\n");
perror("why");
}else if(pid > 0){
while(1){
sleep(3);//让子进程先执行
sprintf(buff,"%d \n",i++);
printf("这是一个父进程");//父进程完成写操作
close(fd[0]);
write(fd[1],buff,sizeof(buff));
}
}else{
while(1){
close(fd[1]);
read(fd[0],buf,sizeof(buf));//没有数据来时,阻塞在这
printf("11111 \nbuf = %s\n111111",buf);
}
}
return 0;
}
2.有名管道fifo
其是类似于mkfifo创建一个虚拟文件myfifo,将数据写进去了而已
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
// int mkfifo(const char *pathname, mode_t mode);
int main()
{
int nread;
char buf[30] = {'\0'};
if(mkfifo("myfifo",0600) == -1 && errno != EEXIST)//创建命名管道
{
printf("mkfifo failed\n");
perror("why");
}
int fd = open("./myfifo",O_RDONLY);//以只读的形式打开管道,程序阻塞在这,直到有另一个进程对其执行写操作
if(fd < 0)
{
printf("read open failed\n");
}else
{
printf("read open successn\n");
}
while(1)
{
nread = read(fd,buf,sizeof(buf));
printf("read %d byte,context is:%s\n",nread,buf);
}
close(fd);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
// int mkfifo(const char *pathname, mode_t mode);
int main()
{
int nread;
char buf[30] = "message from myfifo";
if(mkfifo("myfifo",0600) == -1 && errno != EEXIST)//创建命名管道
{
printf("mkfifo failed\n");
perror("why");
}
int fd = open("./myfifo",O_WRONLY);//打开管道,程序阻塞在这,直到其他进程为读而打开它
if(fd < 0)
{
printf("write open failed\n");
}
else
{
printf("write open success\n");
}
while(1)
{
sleep(1);
write(fd,buf,strlen(buf));
}
close(fd);
return 0;
}
3.消息队列
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
struct msgbuf sendbuf={888,"message from send"};
struct msgbuf readbuf;
key_t key;
if((key = ftok(".",'z')) < 0){
printf("ftok error\n");
}
int msgId = msgget(key,IPC_CREAT|0777);
if(msgId == -1){
printf("get quen failed\n");
}
msgsnd(msgId,&sendbuf,strlen(sendbuf.mtext),0);
printf("send over\n");
msgrcv(msgId,&readbuf,sizeof(readbuf.mtext),999,0);
printf("read from get is:%s\n",readbuf.mtext);
msgctl(msgId,IPC_RMID,NULL);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
struct msgbuf readbuf;
memset(readbuf.mtext, '\0', sizeof(readbuf.mtext));
struct msgbuf sendbuf={999,"thank for your reach"};
key_t key;
//获取key值
if((key = ftok(".",'z')) < 0){
printf("ftok error\n");
}
int msgId = msgget(key,IPC_CREAT|0777);
if(msgId == -1){
printf("get quen failed\n");
perror("why");
}
msgrcv(msgId,&readbuf,sizeof(readbuf.mtext),888,0);
printf("read from send is:%s\n",readbuf.mtext);
msgsnd(msgId,&sendbuf,strlen(sendbuf.mtext),0);
msgctl(msgId,IPC_RMID,NULL);
return 0;
}
4.共享内存
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
// int shmget(key_t key, size_t size, int shmflg);
// void *shmat(int shmid, const void *shmaddr, int shmflg);
// int shmdt(const void *shmaddr);
int main()
{
int shmId;
key_t key;
char *shmaddr;
if((key = ftok(".",1)) < 0){
printf("ftok error\n");
}
shmId = shmget(key, 1024*4, IPC_CREAT|0666);//内存大小必须得是MB的整数倍
if(shmId == -1){
printf("shmget error\n");
exit(-1);
}
/*第二个参数一般写0,让linux内核自动分配空间,第三个参数也一般写0,表示可读可写*/
shmaddr = shmat(shmId, 0, 0);
printf("shmat OK\n");
strcpy(shmaddr,"I am so cool");
sleep(5);//等待5秒,让别的进程去读
shmdt(shmaddr);
shmctl(shmId, IPC_RMID, 0);//写0表示不关心
printf("quit\n");
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
// int shmget(key_t key, size_t size, int shmflg);
// void *shmat(int shmid, const void *shmaddr, int shmflg);
// int shmdt(const void *shmaddr);
int main()
{
int shmId;
key_t key;
char *shmaddr;
if((key = ftok(".",1)) < 0){
printf("ftok error\n");
}
shmId = shmget(key, 1024*4, 0);//内存大小必须得是MB的整数倍
if(shmId == -1){
printf("shmget error\n");
exit(-1);
}
/*第二个参数一般写0,让linux内核自动分配空间,第三个参数也一般写0,表示可读可写*/
shmaddr = shmat(shmId, 0, 0);
printf("shmat OK\n");
printf("data : %s\n",shmaddr);
shmdt(shmaddr);
return 0;
}
5.信号
6.信号量
在这里插入代码片