嵌入式学习-IO线程与进程-Day7
一、思维导图
二、模拟面试
1.线程和进程的区别
异
1.进程是资源分配的最小单位,线程是执行任务的最小单位
2.颗粒度不一,进程分配4G的虚拟内存,线程占用8K内存
3.进程之间的资源相互独立;同一进程中的线程共享进程的资源
4.线程是进程的执行单元,一个进程中可包含多个线程
同:
1.都能实现多任务并发执行
2.都遵循时间片轮巡调度
2.如何实现线程同步,举例说明
同步指多个线程有先后顺序的执行,同步是为了防止多任务并发执行时的竞态,保护临界资源
实现:无名信号量,或者条件变量。
无名信号量:本质是维护了一个value值(一个全局变量),当每个线程要执行时,先申请该value值。如果申请成功,则value减1;如果申请时value为0,则在申请处阻塞,直到另一个线程将value值增加到大于0。
3.互斥的概念以及实现
互斥指多个线程同一时间只允许一个执行
实现:互斥锁,本质是一个临界资源,当某个线程抢到该资源后,其他线程只能处于等待状态,直到该线程释放了锁资源。
4.fork()调用后,父子进程的执行顺序?如何共享资源?
没有先后顺讯。创建子进程后,会共享创建出子进程之前的所有资源
5.什么是僵尸进程,如何避免
僵尸进程指子进程退出后,父进程没有为其回收资源
子进程退出时会发出SIGCHLD信号,可以捕获信号将该进程回收
6.linux支持的进程间的通信机制
七种:无名管道、有名管道、信号、消息队列、共享内存、信号灯集、套接字。
7.消息队列在进程间通信是如何工作的
允许一个或多个进程写入消息,并由一个或多个进程读取,读取后的消息消失。当程序关闭后,如果消息没有被读取,消息还存在
三、作业
1.使用消息队列完成两个进程之间相互通信
test1.c
#include <myhead.h>
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
struct msgbuf
{
long mtype; //消息类型
char mtext_1[1024];//消息正文
char mtext_2[1024];
};
int main(int argc, const char *argv[])
{
//创建key值
key_t key=0;
if((key=ftok("/home/china",'a'))==-1)
{
perror("ftok error");
return -1;
}
printf("key=%#x\t",key);
//使用key值创建消息队列
int msqid=0;
if((msqid=msgget(key,IPC_CREAT|0664))==-1)
{
perror("msgget error");
return -1;
}printf("msqid=%d\n",msqid);
//创建进程
pid_t pid=fork();
if(pid==0)
{
//子进程写入1数据
struct msgbuf buf={.mtype=100};
while(1)
{
scanf(" %s",buf.mtext_1);
msgsnd(msqid,&buf,SIZE,0); //0表示阻塞
if(strcmp(buf.mtext_1,"quit")==0)
break;
printf("发送成功\n");
}
exit(EXIT_SUCCESS);
}else if(pid>0)
{
//父进程读取3数据
struct msgbuf buf={.mtype=200};
while(1)
{
msgrcv(msqid,&buf,SIZE,200,0); //200指取mtype的值
//0表示阻塞
if(strcmp(buf.mtext_2,"quit")==0)
break;
printf("收到了:%s\n",buf.mtext_2);
}
wait(NULL);
//删除消息队列
if(msgctl(msqid,IPC_RMID,NULL)==-1)
{
perror("msgctl error");
return -1;
}
}else
{
perror("pid1 create error");
return -1;
}
return 0;
}
test2.c
#include <myhead.h>
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
struct msgbuf
{
long mtype; //消息类型
char mtext_1[1024];//消息正文
char mtext_2[1024];
};
int main(int argc, const char *argv[])
{
//创建key值
key_t key=0;
if((key=ftok("/home/china",'a'))==-1)
{
perror("ftok error");
return -1;
}
printf("key=%#x\t",key);
//使用key值创建消息队列
int msqid=0;
if((msqid=msgget(key,IPC_CREAT|0664))==-1)
{
perror("msgget error");
return -1;
}printf("msqid=%d\n",msqid);
//创建进程
pid_t pid=fork();
if(pid==0)
{
//子进程写入3数据
struct msgbuf buf={.mtype=200};
while(1)
{
scanf(" %s",buf.mtext_2);
msgsnd(msqid,&buf,SIZE,0); //0表示阻塞
if(strcmp(buf.mtext_2,"quit")==0)
break;
printf("发送成功\n");
}
exit(EXIT_SUCCESS);
}else if(pid>0)
{
//父进程读取1数据
struct msgbuf buf={.mtype=100};
while(1)
{
msgrcv(msqid,&buf,SIZE,100,0); //100指取mtype100的值
//0表示阻塞
if(strcmp(buf.mtext_1,"quit")==0)
break;
printf("收到了:%s\n",buf.mtext_1);
}
wait(NULL);
}else
{
perror("pid1 create error");
return -1;
}
return 0;
}
运行结果