多线程问题

在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。

http://www.cnblogs.com/Rosanna/p/3581835.html

一.概念题

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分别为A、B、C,每个线程将自己的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

时间: 2024-10-18 10:22:33

多线程问题的相关文章

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

Spring多线程

Spring是通过TaskExecutor任务执行器来实现多线程和并发编程的.使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor.而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步的支持,并通过在实际执行的Bean的方法中使用@Async注解来声明其是一个异步任务. 实例代码: (1)配置类 package com.lwh.highlight_spring4.ch3.taskexecutor; /**

python进阶学习(一)--多线程编程

1. 多线程 概念:简单地说操作系统可以同时执行多个不用程序.例如:一边用浏览器上网,一边在听音乐,一边在用笔记软件记笔记. 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务"一起"执行(实际上总有一些任务不在执行,因为切换任务的熟度相当快,看上去一起执行而已) 并行:指的是任务数小于等于CPU核数,即任务真的是一起执行的. 2. 线程 概念:线程是进程的一个实体,是CPU调度和分派的基本单位. threading--单线程执行: 1 import ti

多线程的实现及其安全问题

一.进程和线程概述 1.进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动,简单来说开启一个程序就开启了一个进程: 如果开启多个进程,它们之间是由于CPU的时间片在相互的切换: 2.线程:开启一个进程的一个任务,对于多线程:每一个线程都在争夺CPU的执行权(CPU的执行权具有随机性): 如果一个程序的执行路径有多条,那么该线程是多线程;反之,就单线程线程:线程是依赖于进程存在的! 3.Jvm是多线程 -- 至少开启了两条线程 main方法 主线程 gc() 垃圾回收线程 二.多线程

多线程和多进程的区别与联系

1.单进程单线程:一个人在一个桌子上吃菜.2.单进程多线程:多个人在同一个桌子上一起吃菜.3.多进程单线程:多个人每个人在自己的桌子上吃菜. 多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了...此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢. 1.对于 Windows 系统来说,[开桌子]的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜.因此 Windows 多线程学习重点

Python有了asyncio和aiohttp在爬虫这类型IO任务中多线程/多进程还有存在的必要吗?

最近正在学习Python中的异步编程,看了一些博客后做了一些小测验:对比asyncio+aiohttp的爬虫和asyncio+aiohttp+concurrent.futures(线程池/进程池)在效率中的差异,注释:在爬虫中我几乎没有使用任何计算性任务,为了探测异步的性能,全部都只是做了网络IO请求,就是说aiohttp把网页get完就程序就done了. 结果发现前者的效率比后者还要高.我询问了另外一位博主,(提供代码的博主没回我信息),他说使用concurrent.futures的话因为我全

多线程(一)

这边来谈谈java中,我对对多线程的理解 在了解多线程前,先说说进程. 进程就是正在运行的应用程序.  当你打开任务管理器的时候,你就会发现很多的进程. 而我们要说的线程,就是依赖于进程而存在的,一个进程可以开启多个线程. Thread类 说到线程,就必须来说说Thread类. Thread类是说有线程的父类.具体请参见api 线程的创建以及执行(图解如下) 继承Thread类,或者实现rennable接口. 当继承了父类后,需要重写父类的run方法,这个run方法里面就写你要执行的代码,当这个

多线程下的单例-double check

话不多说直接上代码: public sealed class Singleton { private static Singleton _instance = null; // Creates an syn object. private static readonly object SynObject = new object(); Singleton() { } public static Singleton Instance { get { // Double-Checked Lockin

笔记:多线程

多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务,通常每个任务称为一个线程(thread),他是线程控制的简称,可以同时运行一个以上线程的程序称为多线程程序(multithreaded):多线程和多进程有哪些区别呢,本质的区别在于每个进程拥有自己的一整套变量,而线程则是共享数据,Java中启动一个线程的代码如下: // 线程任务的具体实现接口 ????public interface Runnable { public abstract void run(); ????} /

多线程

1.线程的概念? 多线程,就类似与操作系统中的多进程.简单的讲,就是可 以同时并发执行多个任务,处理多件事情.这与我们经常所 谓的边唱边跳,边说边做事一个道理.? 线程是一个轻量级的进程,一个进程中可以分为多个线程. 比起进程,线程所耗费的系统资源更少,切换更加容易 /* * 进程是操作系统中的一个任务,一个程序启动运行,就会创建 * 一个(或多个)进程. * 线程是轻量级的进程.进程会有自己独立的内存空间与资源.一个进程 * 下会存在一个(或多个)线程.线程为进程的执行单元.线程本身不含有 *