这几天在看看笔试题,准备找移动开发的,找到了百度 济南移动终端开发的笔试题,一看吓一跳,很多都忘了,就目前的情况,基本都不会,赶紧拿来以前的笔记,复习一下。
以下是百度济南的笔试题:
1 .利用互斥量和条件变量设计一个消息队列,具有以下功能:
(1) 创建消息队列(消息中所含的元素)(2)消息队列中插入消息
(3)取出一个消息(阻塞方式)
(4)取出第一消息(非阻塞方式)
2 用非递归方法完成二叉树的周游
3 讲下cnwap 和cnnet的区别
4 设计一个内存管理策略,要求可以保证多线程时的安全,防止内存越界等,效率不低于
malloc/free 函数
会的网友可以给我发消息啊。
今天先从看看进程控制。
进程是60年代初首先由麻省理工学院的MULTICS系统和IBM公司的CTSS/360系统引入的。
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。
在linux里,创建进程的函数有fork( )和vfork( )
| fork | Vfork |
头文件 | #include<unistd> | #include<unistd.h> |
函数原型 | Int fork(void) | Int vfork(void) |
返回值 | 子进程返回0,父进程返回子进程ID,出错返回-1 | |
区别 | 1. fork()创建的子进程拷贝父进程的数据段,堆栈段。Vfork()创建的子进程与父进程共享数据段 2. fork()的父子进程的顺序不定,但是vfork()是子进程先运行 3. vfork()创建的子进程在调用exec()或exit()这两个函数前,如果子进程依赖于父进程的进一步动作,则会导致死锁 |
在来段例子的代码
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
/*
* 程序入口
* */
int main(void)
{
pid_t child;
/* 创建子进程 */
if((child=fork())==-1)
{
printf("Fork Error : %s\n", strerror(errno));
exit(1);
}
else
{
if(child==0) // 子进程
{
printf("I am the child: %d\n", getpid());
exit(0);
}
else //父进程
{
printf("I am the father:%d\n",getpid());
return 0;
}
}
}
运行结果是,两句话都打印出来了,说明创建了两个进程,因为if else是互斥的,如果只有一个进程,那就只会打印一个。
再看看,vfork()的例子代码:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
/*
* 程序入口
* */
int main(void)
{
pid_t child;
/* 创建子进程 */
if((child=vfork())==-1)
{
printf("Fork Error : %s\n", strerror(errno));
exit(1);
}
else
{
if(child==0) // 子进程
{
sleep(1); //子进程睡眠一秒
printf("I am the child: %d\n", getpid());
exit(0);
}
else //父进程
{
printf("I am the father:%d\n",getpid());
exit(0);
}
}
}
结果为,先打印 I am the child ,然后是 I am the father,这就体现了vfork()的区别了