题目2009校园招聘NS试题(一) 一、编程题(30分) 现代的处理器提供了compare-and-swap原子操作:int compare_and_swap(int * pv, const int cv, const int nv);即比较*pv与cv,如果相等,则把*pv值替换为nv并返回*pv原值,否则返回*pv的值。请利用上述原子操作实现如下操作:int inc_if_gt_zero(int * pv);即如果*pv > 0,则把*pv加1并返回修改后的*pv,否则返回*pv。结果要线程安全且不使用锁、信号灯、互斥量、临界区或类似机制。 二、算法题(35分) 题目:假设有一台机器A,有1G内存,另外若干台机器(B、C、D……)通过网络TCP向机器A传输数据,A机器把接收到的数据写入硬盘。B、C、D等机器的数据按记录传输,每条记录大小范围:1M~16M。为了保证每条记录的原子性,B、C、D等机器每次先向A汇报数据量大小,然后再进行数据传输。汇报数据大小时,A机器会给记录分配一个序号,写入文件时每个记录按序号顺序、原子写入。B、C、D等机器处理速度和网络速度都不尽相同,因此汇报数据大小之后,记录数据传递到A的顺序可能不一定按分配好的序号顺序到达。现在要求给A上程序设计一个数据结构,利用该数据结构能高效的接收数据并顺序高效的写入磁盘(也即是不能序号大的记录先写,然后再回写序号小的记录;也不能接收到几十个字节就写一次磁盘)。 三、系统设计题(35分) 现有计算机的内存大部分为易失性内存,一旦断电内存中的数据就会全部丢失,所以操作系统的设计充分的考虑了易失性内存的特点。
问:如果在以后内存全部为非易失性内存,那么应该如何设计新的操作系统,或者说需要对现有的操作系统做哪些修改和改进?
问:如果在以后内存全部为非易失性内存,那么应该如何设计新的操作系统,或者说需要对现有的操作系统做哪些修改和改进?
{
for(; ;)
{
int r = *pv;
if (r <=0) return r;
if (r == compare_and_swap(pv, r, r+1))
return r+1;
}
}
{
return compare_and_swap(pv, -(*pv), *pv) == 0 ? 0 : compare_and_swap(pv, abs(*pv), *pv + 1);
}
int share = 1;//用cmpxchg实现CAS
int compare_and_swap(int *pv,const int cv,const int nv)
{
int rv=*pv;
__asm{
mov eax,cv
mov ecx,pv
mov ebx,nv
cmpxchg [ecx],ebx
}
return rv;
}int inc_if_gt_zero(int *pv)
{
int ret = 0;
int cv;
int nv;
while(1)
{
//执行一次,得到*pv的当前值,必须确保不修改pv的原始值
//ret = compare_and_swap(pv,-1,-1);
//直接取就可以
ret = *pv;
//如果该值小于等于0,可以安全的返回ret值
if(ret<=0) return ret;
//否则需要对pv作加一的操作
cv = ret;
nv = ret+1;
//ret = compare_and_swap(pv,cv,nv);
//*pv = nv; //改为普通赋值速度会更快,但运行结果随机化
*pv = *pv + 1;
if(ret==cv) return ret+1;
}
}
//工作线程,操作pv,要求:确保线程的运行是无序的
DWORD WINAPI ThreadFun(LPVOID lpParam)
{
int id = (int)lpParam;
int i;
srand((unsigned)time(0));
//打乱线程的第一次运行顺序
for(i=0;i<5;i++) Sleep(200*(1+rand()*5/RAND_MAX));
for(i=0;i<20;i++)
{
Sleep(20*(1+rand()*2/RAND_MAX));
printf("Thread %d NO. %d\n",id,i);
Sleep(20*(1+rand()*2/RAND_MAX));
inc_if_gt_zero(pv);//*************************** }
printf("Thread %d returned\n",id);
return 0;
}//主函数测试
// 开20个线程,每个线程对share通过inc_if_gt_zero加1操作20次
// share初值可以任意设置
// 如果share<=0,值不变
// 如果share>0,最终结果应该是: 初值+400
int main(void)
{ int i; srand((unsigned)time(0));
pv = &share;
for(i=0;i<20;i++) CreateThread(NULL,0,ThreadFun,(LPVOID)i,0,NULL);
//主线程用原始方法等待所有线程终止
getchar();
printf("运行结果: share = %d\n",share);
}