题目总结

来源:互联网 发布:tech域名不能备案 编辑:程序博客网 时间:2024/06/04 22:54

1.概念题

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

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

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

2.多线程同步和互斥有何异同?在什么情况下分别使用他们?

同步指线程间的一种制约关系,一个线程的执行依赖于另一个线程的消息,消息未到达就等待,到达就被唤醒;
互斥指对于一个进程的共享资源,任何时候只有一个线程可以访问,其他要访问的线程必须等待,直到该线程释放资源;

线程同步一般是当多个线程相互协作,存在相互依赖的关系;线程互斥是包括临界资源等的访问,相互线程之间是互斥访问。


3.多线程同步和互斥有几种实现方法?

线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。
用户模式下的方法有:临界区。内核模式下的方法有:事件,信号量,互斥量。


2.选择题

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

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

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

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


3.综合题

一个全局变量tally,两个线程并发执行(代码段都是ThreadProc),问两个线程都结束后,tally取值范围。 
inttally = 0;//global voidThreadProc() {       for(inti = 1; i <= 50; i++)             tally += 1; }

    当两线程串行时,结果最大为100,当某个线程运行结束,而此时另外一个线程刚取出0,还未计算时,结果最小为50。


4.编程题

知识:

关于线程操作的函数
#include <pthread.h>int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);int pthread_join (pthread_t tid, void ** status);pthread_t pthread_self (void);int pthread_detach (pthread_t tid);void pthread_exit (void *status);

互斥锁的相关操作函数如下:

#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t * mptr); int pthread_mutex_unlock(pthread_mutex_t * mptr); 

条件变量:
#include <pthread.h>int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr); int pthread_cond_signal(pthread_cond_t *cptr); 
int pthread_cond_broadcast (pthread_cond_t * cptr);


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

#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <string.h> #define DEBUG 1   int num = 0; pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t qready=PTHREAD_COND_INITIALIZER;void* thread_func(void *arg){    int param = (int) arg;    int i;        for(i = 0; i < 10; i++)    {        pthread_mutex_lock(&mylock);                while(param != num)            pthread_cond_wait(&qready, &mylock);                printf("%c", param + 'A');        num = (num + 1) % 3;                pthread_mutex_unlock(&mylock);        pthread_cond_broadcast(&qready);    }        return (void *)0;}int main(){    int i;    pthread_t tid[3];    void *tret;        for(i = 0; i < 3; i++)        pthread_create(&tid[i], NULL, thread_func, (void *) i);    for(i = 0; i < 3; i++)        pthread_join(tid[i], &tret);    }

首先开辟3个子线程,分别为a,b,c,其中a负责打印'A', b负责打印'B',c负责打印'C'。然后abc开始执行,首先a,b,c都去尝试加锁,其中有一个加锁成功,另外两个则阻塞等待在那里。不妨假设b加锁成功(其实这个可以控制放a先加锁成功);这时a和c线程都阻塞等待加锁,b线程开始执行,当执行到while(param != num),因为他的param是1所以!= num(0),所以他会执行下面的条件变量等待语句,于是他暂时释放当前锁,然后等待在条件变量qread之上。因为此时b释放了锁,那么a和c线程就有机会进入循环了。可以发现如果c获得了锁他的状态和b一样都是阻塞在条件变量之上。于是条件变量就有了一个队列:c b
这时a就可以执行下面的语句了因为在a线程不执行条件变量等待,然后打印出'A',把num置为1,以此可以让b线程执行。然后a线程释放锁,唤醒所有阻塞在条件变量里面的线程(pthread_cond_broadcast(&qready);),然后b和c就都唤醒了。于是再一次去抢占加锁,不妨假设c抢到了锁,然后他再一次被伤害了,因为他需要执行while语句里面的条件变量等待,此时的条件变量将阻塞a和c线程,于是c再一次被阻塞,理所当然的b执行了线程打印出了‘B',后面的故事就一样了。
如此便可以有效的控制线程的输出顺序!

(2) 有一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);}

(3)子线程循环 5次,接着主线程循环 10 次,接着又回到子线程循环 5 次,接着再回到主线程又循环 10次,如此循环3次,试写出代码。 

#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);}



参考:
http://www.cnblogs.com/Rosanna/p/3581835.html
http://www.cnblogs.com/skynet/archive/2010/10/30/1865267.html





0 0