操作系统进程管理实验【3】

继上次的创建线程后,我又带着一段新的代码来了QAQ

这个代码也和线程有关,pthread_create()函数我上次提到了,就不再赘述了,不知道的朋友可以百度或者看我的进程管理实验【2】。今天的代码不仅和线程有关,它其实描述的是死锁

死锁是什么呢?

死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

啥是互相竞争资源?我上次提到在操作系统中有一些资源在一个时间点上只能被一个进程访问,这些资源被称为临界资源,为了实现临界资源的同步访问,我们加了一个锁,当进程获得这个锁后它才可以访问临界资源,说到着,我们试着想一想若是一个资源必须获得两个锁才可以访问,当一个进程获得一个锁后,另一个进程恰巧获得了另一个锁,此时第一个进程得不到第二个锁,第二个进程得不到第一个锁,就产生了死锁

我们来看一段代码:

#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <pthread.h>

#define LOOP_TIMES 10000
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;	//静态初始化互斥锁
void* thread_worker(void*);
void critical_section(int thread_num, int i);

int main(void)

{
        int rtn, i;
        pthread_t pthread_id = 0; /* 存放子线程的id */
        rtn = pthread_create(&pthread_id, NULL, thread_worker, NULL );	//第一个null表示设置线程的属性,第二个null表示万能指针arg,thread_worker表示线程从thread_worker函数的地址开始运行
        if(rtn != 0)	//出错
        {
                printf("pthread_create ERROR!\n");
                return -1;

        }
        for (i=0; i<LOOP_TIMES; i++)
        {
                pthread_mutex_lock(&mutex1);	//锁操作
                pthread_mutex_lock(&mutex2);	//锁操作
                critical_section(1, i);
		pthread_mutex_unlock(&mutex2);	//解锁操作
                pthread_mutex_unlock(&mutex1);	//解锁操作

        }
        pthread_mutex_destroy(&mutex1);
        pthread_mutex_destroy(&mutex2);		//注销互斥锁

        return 0;
}
void* thread_worker(void *p)
{
        int i;
        for (i=0; i<LOOP_TIMES; i++)
        {
                pthread_mutex_lock(&mutex2);
		pthread_mutex_lock(&mutex1);
                critical_section(2, i);
                pthread_mutex_unlock(&mutex2);
        	pthread_mutex_unlock(&mutex1);
        }
}

void critical_section(int thread_num, int i)
{
        printf("Thread%d:%d\n", thread_num, i);
}

前面的声明很简单,定义了一个循环次数和两个锁,我们直接看主程序:

        rtn = pthread_create(&pthread_id, NULL, thread_worker, NULL );	//第一个null表示设置线程的属性,第二个null表示万能指针arg,thread_worker表示线程从thread_worker函数的地址开始运行
        if(rtn != 0)	//出错
        {
                printf("pthread_create ERROR!\n");
                return -1;
        }

从代码可以看出首先创建了一个线程,将它的id赋给了pthread_id,没有传参,线程执行thread_work()函数,若创建出错return。我们先来看线程执行了个啥?

void* thread_worker(void *p)

{
        int i;
        for (i=0; i<LOOP_TIMES; i++)
        {
                pthread_mutex_lock(&mutex2);
		pthread_mutex_lock(&mutex1);
                critical_section(2, i);
                pthread_mutex_unlock(&mutex2);
        	pthread_mutex_unlock(&mutex1);
        }
}

这里其实就是线程通过同时获得两个锁之后访问临界区(访问临界资源的代码段),且这段代码被嵌在了循环中,再来看critical_section(2,i):

void critical_section(int thread_num, int i)
{
        printf("Thread%d:%d\n", thread_num, i);
}

这句打印语句Thread%d其实想告诉我们传进去的2其实代表了这个进程的代号,那1呢?自然是主进程了,这句代码简单的打印了当前的循环次数。按照程序的走向,我们该看下面的代码了:

        for (i=0; i<LOOP_TIMES; i++)
        {
                pthread_mutex_lock(&mutex1);	//锁操作
                pthread_mutex_lock(&mutex2);	//锁操作
                critical_section(1, i);
		pthread_mutex_unlock(&mutex2);	//解锁操作
                pthread_mutex_unlock(&mutex1);	//解锁操作
        }

啥都没变,基本和线程执行的代码一样,唯一有区别的是它拿锁的顺序不同,它先拿的1锁,而线程先拿2锁。其实程序挺简单的,到此我们可以预测一下程序的运行了:主进程和线程互相竞争资源来打印信息,所以开始会有一些信息被打印,到某一时刻时,主进程抢到了1锁,线程抢到了2锁导致系统死锁,程序进入假死状态。

我们来验证一下,为了看的更清楚为加两个打印语句:

        for (i=0; i<LOOP_TIMES; i++)
        {
                pthread_mutex_lock(&mutex1);    //锁操作
                printf("主进程抢到1锁\n") ;
                pthread_mutex_lock(&mutex2);    //锁操作
                critical_section(1, i);
                pthread_mutex_unlock(&mutex2);  //解锁操作
                pthread_mutex_unlock(&mutex1);  //解锁操作
        }

        for (i=0; i<LOOP_TIMES; i++)
        {
                pthread_mutex_lock(&mutex2);
                printf("线程抢到2锁\n") ;
                pthread_mutex_lock(&mutex1);
                critical_section(2, i);
                pthread_mutex_unlock(&mutex2);
                pthread_mutex_unlock(&mutex1);
        }

好了,运行如下:

......一点问题也没有,有点不习惯??????哈哈哈,这样我就能睡觉了。0.0

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.基本系统进程   Csrss.exe:这是子系统服务器进程,负责控制Windows创建或删除线程以及16位的虚拟DOS环境。   System Idle Process:这个进程是作为单线程运行在每个处理器上,并在系统不处理其它线程的时候分派处理器的时间。   Smss.exe:这是一个会话管理子系统,负责启动用户会话。   Services.exe:系统服务的管理工具。   Lsass.exe:本地的安全授权服务。   Explorer.exe:资源管理器。   Spoolsv.exe:管理缓冲区中的打印和传真作业。   Svchost.exe:这个进程要着重说明一下,有不少朋友都有这种错觉:若是在“任务管理器”中看到多个Svchost.exe在运行,就觉得是有病毒了。其实并不一定,系统启动的时候,Svchost.exe将检查注册表中的位置来创建需要加载的服务列表,如果多个Svchost.exe同时运行,则表明当前有多组服务处于活动状态;多个DLL文件正在调用它。   至于其它一些附加进程,大多为系统服务,是可以酌情结束运行的。由于其数量众多,我们在此也不便于一一列举。   在系统资源紧张的情况下,我们可以选择结束一些附加进程,以增加资源,起到优化系统的作用。在排除基本系统及附加进程后,新增的陌生进程就值得被大家怀疑了。 更多内容请看Windows操作系统安装、系统优化大全、系统安全设置专题,或进入讨论组讨论。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值