当前位置: 首页 > news >正文

多线程试题汇总

一.概念题

1.线程的基本概念、线程的基本状态及状态之间的关系?

      线程是进程中某个单一顺序的控制流,是程序执行流的最小单位。线程由线程ID、当前指令指针、寄存器集合和堆栈组成。线程是进程的一个实体,是被系统调度和分配的基本单位,线程与同一进程中的其他线程共享进程的全部资源。

      线程有五种基本状态:新生状态,就绪状态,运行状态,阻塞状态,死亡状态。状态间关系如下图:

2.线程与进程的区别?

      (1)进程是系统资源分配和调度的独立单位;线程是进程的一个实体,是CPU调度和分派的基本单位。      
      (2)系统资源分配给进程;线程与资源分配无关,线程与同一进程内的其他线程共享进程的全部资源。
      (3)不同的进程拥有不同的虚拟地址;同一进程下的不同线程共享同一地址空间。

3.在Windows编程中互斥量与临界区比较类似,请分析一下二者的主要区别。

      (1)临界区不是内核对象,只能用于进程内的线程间同步,速度快;
      (2)互斥量是内核对象,可以用于进程间同步,在核心态进行锁操作,速度慢;
      (3)Linux中只有互斥量,用来保护临界区,保证同一时间只由一个线程访问临界区的共享资源。

4.多线程同步和互斥有何异同?多线程同步和互斥有几种实现方法?在什么情况下分别使用他们?

      同步指线程间的一种制约关系,一个线程的执行依赖于另一个线程的消息,消息未到达就等待,到达就被唤醒;
      互斥指对于一个进程的共享资源,任何时候只有一个线程可以访问,其他要访问的线程必须等待,直到该线程释放资源;
      实现方法分为用户模式和内核模式。用户模式:临界区;内核模式:互斥量,信号量,事件。
      (信号量允许多个线程同时使用共享资源,规定了同时访问共享资源的线程最大数目。
      事件可以实现不同进程中的线程同步操作,并且可以方便的实现多个线程的优先比较等待操作。)

 

二.选择题

1.以下多线程对int型变量x的操作,哪几个不需要进行同步:

       A. x=y;      B. x++;    C. ++x;    D. x=1;

2.多线程中栈与堆是公有的还是私有的

      A:栈公有,堆私有
      B:栈公有,堆公有
      C:栈私有,堆公有
      D:栈私有,堆私有

 

三.编程题

1.子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。 

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<pthread.h>
#include<unistd.h>

int num=1;  //全局变量

static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void *func();

int main()
{
	pthread_t tid;
	int ret=0,i,j;
	if((ret=pthread_create(&tid,NULL,func,NULL))!=0)
		printf("create thread error!\n");
	for(i=0;i<3;i++)
	{

		pthread_mutex_lock(&mutex);
        if(num!=0)
			pthread_cond_wait(&cond,&mutex);
		num=1;
		for(j=0;j<10;j++)
    	{
	    	printf("0");
		}
    	printf("\n");
		pthread_mutex_unlock(&mutex);
		pthread_cond_signal(&cond);
	}
	return 0;
}

void *func()
{
	int i,j;
	for(i=0;i<3;i++)
	{
		pthread_mutex_lock(&mutex);
		if(num!=1)
			pthread_cond_wait(&cond,&mutex);
		num=0;
		for(j=0;j<5;j++)
    	{
	    	printf("1");
		}
		printf("\n");
		pthread_mutex_unlock(&mutex);
		pthread_cond_signal(&cond);
	}
	pthread_exit(0);
}

 

2.编写一个程序,开启3个线程,这3个线程的ID分别为ABC,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC.依次递推。

#include<stdio.h>
#include<stdlib.h>
#include<error.h>
#include<unistd.h>
#include<pthread.h>

int num=0;

static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void *func(void *);

int main()
{
	pthread_t tid[3];
	int ret=0,i;
	for(i=0;i<3;i++)
		if((ret=pthread_create(&tid[i],NULL,func,(void*)i))!=0)
			printf("create thread_%c error\n",i+'A');
   	for(i=0;i<3;i++)
		pthread_join(tid[i],NULL);
	printf("\n");
	return 0;
}

void *func(void *argc)
{
	int i;
	for(i=0;i<10;i++)
	{
		pthread_mutex_lock(&mutex);
	    while(num!=(int)argc)
			pthread_cond_wait(&cond,&mutex);
		printf("%c",num+'A');
		num=(num+1)%3;
		pthread_mutex_unlock(&mutex);
		pthread_cond_broadcast(&cond);
	}
	pthread_exit(0);
}

 

3. 有一int型全局变量g_Flag初始值为0;
在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为1
在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为2
线程序1需要在线程2退出后才能退出
主线程在检测到g_Flag从1变为2,或者从2变为1的时候退出

#include<stdio.h>
#include<stdlib.h>
#include<error.h>
#include<pthread.h>
#include<unistd.h>

int flag=0;

void *thread1(void*);
void *thread2(void*);

static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

int main()
{
	printf("enter main\n");
	pthread_t tid1,tid2;
	int ret=0;
	if((ret=pthread_create(&tid1,NULL,thread1,&tid2))!=0)
		printf("create thread1 error!\n");
	if((ret=pthread_create(&tid2,NULL,thread2,NULL))!=0)
		printf("create thread2 error!\n");
	pthread_cond_wait(&cond,&mutex);
	printf("leave main\n");
	return 0;
}

void *thread1(void *argc)
{
	printf("this is thread1\n");
	pthread_mutex_lock(&mutex);
	if(flag==2)
		pthread_cond_signal(&cond);
	flag=1;
	pthread_mutex_unlock(&mutex);
	pthread_join(*(pthread_t*)argc,NULL);
	pthread_exit(0);
}

void *thread2(void *argc)
{
	printf("this is thread2\n");
	pthread_mutex_lock(&mutex);
	if(flag==1)
		pthread_cond_signal(&cond);
	flag=2;
	pthread_mutex_unlock(&mutex);
	pthread_exit(0);
}

 

 

 

题目摘自:

1.http://blog.csdn.net/morewindows/article/details/7392749

2.http://www.cnblogs.com/skynet/archive/2010/10/30/1865267.html

转载于:https://www.cnblogs.com/Rosanna/p/3581835.html

相关文章:

  • CentOS上配置LVS DR集群
  • Android应用加入微信分享
  • nowrap要与回车换行符结合才有意义
  • XMPP 基础
  • 初学3ds Max,做了个雪人,大家来评评哪个更好看
  • 精彩十年(3)——初露锋芒
  • Java常用工具类的使用
  • 精彩十年(4)——缔造神话
  • HibernateDaoSupport实现分页技术总结
  • 新作《.NET 4.0面向对象编程漫谈》之序“穿越梦想、起锚远航”
  • java synchronized详解(非常详细)
  • 123456789分割成12,34,56,789
  • 分享代码
  • C语言实现 字符串过滤并修改并返回个数
  • 记录:对这次转正的一些预测
  • SegmentFault for Android 3.0 发布
  • 【附node操作实例】redis简明入门系列—字符串类型
  • isset在php5.6-和php7.0+的一些差异
  • Java IO学习笔记一
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Python爬虫--- 1.3 BS4库的解析器
  • SpiderData 2019年2月25日 DApp数据排行榜
  • STAR法则
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 关于extract.autodesk.io的一些说明
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 算法---两个栈实现一个队列
  • 微服务核心架构梳理
  • 为什么要用IPython/Jupyter?
  • 消息队列系列二(IOT中消息队列的应用)
  • 新手搭建网站的主要流程
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • #### go map 底层结构 ####
  • #{}和${}的区别?
  • #WEB前端(HTML属性)
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (3)nginx 配置(nginx.conf)
  • (JS基础)String 类型
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (图)IntelliTrace Tools 跟踪云端程序
  • (一)认识微服务
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .apk文件,IIS不支持下载解决
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .net web项目 调用webService
  • .NET 表达式计算:Expression Evaluator
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • /etc/skel 目录作用