kernel hang_猜单词游戏(类似于Hang子手)

这是一个Perl编写的挂人游戏脚本,类似于经典的游戏Hangman。脚本包含游戏逻辑、计分系统和用户界面,使用CGI模块处理HTTP请求。游戏提供有限次数的猜测机会,错误猜测会减少剩余尝试次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kernel hang

这不是“ Howto”文章,而是完整的脚本。 几年前,我为另一个论坛的比赛写了这个脚本,从那以后它真的只是在收集灰尘。

如果您不了解某些代码,请询问有关脚本如何工作的问题。 这并非旨在提供技术支持,而是出于学习目的。 毫无疑问,可以对代码进行改进,因此,如果您发现有使自己感到胆怯的话题,可以随意讨论。 它应该是CGI脚本以及如何使用CGI模块和其他几个核心模块的一个很好的例子。

我希望它可以用作学习工具,但是如果有人想将其发布到网站上供访问者使用,那就可以了。

没有对该脚本的支持,但是如果您尝试使用它并使其无法运行,我可能会尝试通过此论坛为您提供帮助。 但我不会尝试并尝试帮助您使其运行。 如果在提出一些建议后仍无法正常工作,我将不再提供帮助。

附带有一个单词文件,该单词文件多于2,000个单词,难于猜测。 一个文件具有按字母顺序排列的单词,另一个文件words.dat是用于游戏的文件。 单词以随机顺序排列,并以空格分隔,这是脚本编写所希望找到的空格。 不应有粗俗的字眼,但您不妨检查一下。

由于此论坛不允许上传.pl文件,因此将perl脚本附加为wordguess.txt。 如果使用该文件,只需将名称更改为wordguess.pl

问候,

凯文

#!/usr/bin/perl -T 
######################################################
# Wordguess Game, similar to Hangman
# Kevin Ruggles 2004
# There is no help or tech support for this script.
# Use at your own risk.
# Edit and distribute as you like.
# See comments in script for hints on how to set it up
# or to change stuff.
######################################################   
####################################
####  script environment stuff  ####
####  do not edit unless you    ####
####  know what you are doing!  ####
####################################
use CGI qw(-no_xhtml);
#use CGI::Carp qw(fatalsToBrowser);
$CGI::POST_MAX = 128;  # max 128 byte posts, we don't need much for this script so keep it low
$CGI::DISABLE_UPLOADS = 1;  # no uploads, to prevent funny business
use Fcntl;
use Tie::File;
use strict;
use warnings; 
##########################################################
####  Paths to files                                  ####
####  Should be above the web root folder.            ####
####  Create a folder and name it hangman.            #### 
####  Put the words.txt file in it.                   ####
####  Change "/home/yoursite" to work on your website ####
##########################################################
my $path_words = '/home/yoursite/hangman/words.txt';
my $path_games = '/home/yoursite/hangman/data/'; 
########################################################
####  scoring data - you can edit them if you like  ####
########################################################
my @v = q(3 7 10 15);
my %points = (
   a=>$v[0],e=>$v[0],i=>$v[0],o=>$v[0],u=>$v[0],
   b=>$v[1],c=>$v[1],d=>$v[1],f=>$v[1],g=>$v[1],
   h=>$v[1],l=>$v[1],m=>$v[1],n=>$v[1],p=>$v[1],
   r=>$v[1],s=>$v[1],t=>$v[1],
   j=>$v[2],k=>$v[2],y=>$v[2],
   v=>$v[3],q=>$v[3],w=>$v[3],x=>$v[3],z=>$v[3]
); 
############################################################
####  Appearance stuff - you can edit them if you like. ####
####  The code is CSS and is inserted as an inline      ####
####  style sheet or directly into html tags. Its up to ####
####  you to figure it out.                             ####
############################################################
my $body_definitions = qq(
body {
   background-color:#C0C0FF;
   font-family:Verdana;
   font-size:16px;
}
input {
   font-family:Verdana;
   font-size:12px;
   font-weight:bold;
   background-color:#C0C0FF;
   border:solid 1px #0000C0;
}
);
my $div_enter_page = qq(background-color:#D4D5EC; text-align:center; width:400px; padding:8px 5px 0 5px; border:solid 1px #0000C0; margin-top: 15%; margin-left: auto; margin-right: auto;);
my $div_style = qq(background-color:#D4D5EC; text-align:center; width:480px; padding:8px 0 0 0; border:solid 1px #0000C0; margin-top: 15%; margin-left: auto; margin-right: auto;);
my $H1 = qq(font-family:Arial; font-size:24px;);
my $rules = qq(font-size:10pt;width:100%;text-align:left;padding:0 5px 0 5px;);
my $secret_word_span = qq(color:#0000C0;letter-spacing:5px;font-size:24px;font-weight:bold;font-family:Courier;);
my $text_field = qq(background-color:cornsilk;text-align:center;); 
########################################################
####  game options - you can edit them if you like  ####
########################################################
# maximum number of incorrect tries
my $max_tries = 10; 
# maximum amount of time in seconds to complete a game (60 = 1 minute, etc)
# set to zero '0' or leave blank '' to NOT have a time limit.
my $max_time = 60; 
# the number of days until old games that were not deleted by the script during play
# will be deleted, the minimum value is one '1' (one day more or less).
# set to zero '0' or leave blank '' to NOT auto delete old game files.
my $delete = 1; 
##############################################
####  you should not edit below here      ####
####  unless you know what you are doing! ####
##############################################
my $q = new CGI;
print $q->header(); 
my ($flag,$t,%h,$id) = (0,time,'',''); 
if ($q->param('new_game') || $q->param('start_game') || $q->param('submit') || $q->param('hint')) {
   GetData();
   my $this_guess = ProcessData() unless $q->param('new_game') || $q->param('start_game');
   Win()  if ($h{'word'} eq $h{'revealed'} && $h{'tries_left'} <= $max_tries);
   Lose() if ($t >= $h{'time'} && $max_time);
   Lose() if ($h{'tries_left'} < 1 && $this_guess);
   PrintGame();
   PrintData();
   AutoDelete() if $delete;
}
else {Enter()}
exit(0);
########################################
####  normal termination of script  ####
######################################## 
#######################
####  subroutines  ####
#######################
sub AutoDelete {
   $path_games .= '/' unless $path_games =~ m/\/$/; # make sure we have the trailing slash
   my @games = <$path_games*.game>;
   for (@games) {
        if (/$path_games([\w]{20})\.game/) {# untaint the path
           my $game = "$path_games$1.game";
         unlink($game) if (int(-M $game) >= $delete);
      }
      else {next;}
   }
} 
sub DeleteOld {
   my $old_id = shift;
   die "Unable to continue.\n" unless ($old_id =~ m/^([\w.-]+)$/); #untaint $old_id
   $old_id = "$path_games$1.game";
   unlink($old_id);
   undef $old_id;
} 
sub EndHTML {
   print $q->start_form(-name=>'hangman'),
         $q->submit (-name=>'new_game', -label=>'Play Again'),
         $q->end_form,
         "\n</div>\n",
         $q->end_html;
   exit(0);
} 
sub Enter {
   my $the_time = 'run out.';
   $the_time = 'run out or the time runs out.' if $max_time;
   my $the_time2 = '';
   $the_time2 = "and $max_time seconds" if $max_time;
   print $q->start_html(-title=>'Word Guess / Hangman!',-style=>"$body_definitions",-onLoad=>'document.hangman.start_game.focus()'),
         qq~
<div style="$div_enter_page">
   <h1 style="$H1">Lets Play Word Guess (Hangman)!</h1>
      <div style="$rules">
         <b>&nbsp;&nbsp;&nbsp;The Rules:</b>
            <ol>
                <li>Guess letters to reveal the secret word.</li>
                <li>You win if you guess the secret word before your tries remaining $the_time</li>
                <li>You have $max_tries tries $the_time2 to start with.</li>
                <li>An incorrect guess will take away one try.</li>
                <li>A correct guess will not take away from your $max_tries tries but does add to your total tries.</li>
            </ol>
      </div>
~,
         $q->start_form(-name=>'hangman'),
         $q->submit(-name=>'start_game', -label=>'Start Game'),
         $q->end_form,
         "\n</div>\n",
         $q->end_html;
} 
sub GetData {
   if($q->param('new_game') || $q->param('start_game')) {
      &DeleteOld($q->param('gameid')) if $q->param('gameid');
      $id = &MakeGameId();
      $id = &MakeGameId() if (-e "$path_games$id.game"); #just to be safe
      tie my @DATA, 'Tie::File', $path_words, recsep => ' ', mode => O_RDWR || die print "<h2>$!</h2>\n";
      print "<h1>There are no words. Please upload the words.dat file</h1>" unless @DATA;
      my $word = lc $DATA[int(rand @DATA)];
      untie(@DATA);
      ($h{'hints'},$h{'total'},$h{'word'},$h{'tries_left'},$h{'letters'},$h{'time'}) = (0,0,$word,$max_tries,'',($t+$max_time));
      ($h{'revealed'} = $word) =~ tr/a-z/_/; 
      open(GAME, ">$path_games$id.game") or die print "<h2>Can't find game file: $!</h2>\n";
      print(GAME "$h{'time'}\t$h{'hints'}\t$h{'hint_letters'}\t$h{'total'}\t$h{'word'}\t$h{'tries_left'}\t$h{'letters'}\t$h{'revealed'}");
   }
   else {
      $id = $q->param('gameid');
      die "Unable to continue.\n" unless ($id =~ m/^([\w.-]+)$/); #untaint $id
      $id = $1;
      open(GAME, "$path_games$id.game") or die print "<h2>Can't find game file: $!</h2>\n";
      ($h{'time'},$h{'hints'},$h{'hint_letters'},$h{'total'},$h{'word'},$h{'tries_left'},$h{'letters'},$h{'revealed'}) = split(/\t/,<GAME>);
   }
   close(GAME);
} 
sub GuessLetter {
   my $guess = shift;
   my @word = split(//,$h{'word'});
   my @new_revealed = split(//,$h{'revealed'});
   my ($pass,$count) = (0,0);
   foreach (@word) {
      ($pass,$new_revealed[$count]) = (1,$guess) if ($guess eq $_);
      $count++;
   }
   $h{'revealed'} = join("",@new_revealed);
   return $pass;
} 
sub Hint {
   my $bonk = 0;
   my @word = split(//,$h{'word'});
   my $hint = lc $word[int(rand @word)];
   my %revealed = map {$_ => $_} split(//,$h{'revealed'});
   $bonk++ if $hint eq $revealed{$hint};
   if ($bonk) {&Hint;}
   else {return $hint;}
} 
sub Lose {
   &DeleteOld($q->param('gameid'));
   my ($score,$max_score) = &Score();
   my $effort = '';
   $effort = 'that sucked'  if $score < 1;
   $effort = 'good try'     if $score > 0;
   $effort = 'time ran out' if ($t > $h{'time'} && $max_time);
   print $q->start_html(-title=>'Word Guess / Hangman - Sorry!',-style=>"$body_definitions",-onLoad=>'document.hangman.new_game.focus()'),
         qq~
<div style="$div_style">Sorry, $effort, the secret word was:<p>
   <span style="$secret_word_span">$h{'word'}</span><p>
   Your score was <b>$score</b> of a possible <b>$max_score</b> points.
   <br>
~;
  &EndHTML;
} 
sub MakeGameId {
   my @digits = ('a'..'z', 'A'..'Z', '0'..'9');
   $id .= $digits[int(rand @digits)] for (1..10);
   return ($id.time);
} 
sub PrintData {
   open(GAME, ">$path_games$id.game") || die "$!\n";
   print(GAME "$h{'time'}\t$h{'hints'}\t$h{'hint_letters'}\t$h{'total'}\t$h{'word'}\t$h{'tries_left'}\t$h{'letters'}\t$h{'revealed'}");
   close(GAME);
} 
sub PrintGame {
   my ($time_limit,$color,$t_color) = ('','#000000','#000000');
   if ($h{'tries_left'} < 3) {$color = '#FF0000';}#alert when 2 tries remain
   my $time_left = ($h{'time'} - $t);
   my $t_percent = int($max_time * .2);
   if ($time_left <= $t_percent) {$t_color = '#FF0000';}#alert when %20 of time remains
   $time_limit = qq~Time Remaining: <span style="color:$t_color;font-weight:bold;">$time_left sec</span><br>~ if ($max_time);  
   print $q->start_html( -title=>'Word Guess / Hangman!',-style=>"$body_definitions",-onLoad=>'document.hangman.guess.select()'),
         qq~
<div style="$div_style">
   <span style="font-size:20px;font-weight:bold;">Secret Word: </span>
   <span style="$secret_word_span">$h{'revealed'}</span>
   <p>
~,
         $q->start_form(-name=>'hangman'),
         "Enter a guess: ",
         $q->textfield ( -name=>'guess', -size=>1, -maxlength=>1, -default=>'', -style=>"$text_field", override=>1,),
         "&nbsp;",
         $q->hidden (-name=>'gameid', -default=>$id, override=>1),
         $q->submit (-name=>'submit', -label=>'Submit Guess'),
         qq~
   <p>Tries Remaining: 
   <span style="color:$color;font-weight:bold;">$h{'tries_left'}</span>
   <br>$time_limit
   Total Tries: <b>$h{'total'}</b>
   <br>
   Incorrect Guesses: <b style="letter-spacing:6px;">$h{'letters'}</b>
   <p>
   &nbsp;&nbsp;
~,
         $q->submit(-name=>'hint', -label=>'Hint'),
         "\n   <span style=\"font-size:16px;\"> * </span><p>\n",
         $q->submit(-name=>'new_game', -label=>'New Game'),
         "\n   <p>\n",
         $q->end_form,
         qq~\n   <span style="font-size:10px;">* Takes away 2 tries remaining and adds 2 to total tries.<br>* No points awarded for hints.</span>\n</div>\n~,
         $q->end_html;
} 
sub ProcessData {
   my $this_guess = $q->param('guess');
   $this_guess = &Hint if $q->param('hint');
   $this_guess =~ tr/a-zA-Z//cd; #we only want a-z
   $this_guess = substr $this_guess,0,1; #we only want one character
   if ($this_guess) {
      $h{'total'}++;
      ($h{'tries_left'}-=2,$h{'total'}++,$h{'hints'}++,$h{'hint_letters'} .= $this_guess) if $q->param('hint');
      unless (&GuessLetter($this_guess)) {
         $h{'tries_left'}--;
         $h{'letters'} .= $this_guess;
      }
      return($this_guess);
   }
   else {return(0);}
} 
sub Score {
   # the scoring system is very simple and only intended for fun
   # the basic concept is:
   #   1. each unique letter in a word is given a points value (%points)
   #   2. any letters revealed by using the hint button are not awarded points.
   #   3. the total points are added up and multiplied by the number of tries remaining if any.
    $h{'tries_left'} = 1 if $h{'tries_left'} < 1;
   my ($score,$score2,$max_score) = (0,0,0);
   my %guess = map {$_ => $_ } split(//,$h{'revealed'});
   my %word  = map {$_ => $_ } split(//,$h{'word'});
   my %hints = map {$_ => $_ } split(//,$h{'hint_letters'});
   for (keys %guess) {
        $guess{$_} = 0 if $_ eq $hints{$_};
   }
   $score+=$points{$_}  for values %guess;
   $score2+=$points{$_} for keys %word;
   $max_score = $score2*$max_tries;  # maximum possible score
print qq~   $score = $score*$h{'tries_left'}; # actual score~;
   $score = $score*$h{'tries_left'}; # actual score
   return ($score,$max_score);
} 
sub Win {
   my $time_used = $max_time - ($h{'time'} - $t);
   my $time_stat = '';
   $time_stat = qq~<br>Time: <b>$time_used sec</b>~ if ($max_time);  
   &DeleteOld($q->param('gameid'));
   my ($score,$max_score) = &Score();
   my $congrats = 'Congratulations!';
   $congrats .= ' Perfect Score!' if $score == $max_score;
   print $q->start_html(-title=>'Word Guess / Hangman - Congratulations!',-style=>"$body_definitions",-onLoad=>'document.hangman.new_game.focus()'),
         qq~
<div style="$div_style">
   $congrats<br>You guessed the secret word:
   <p>
   <span style="$secret_word_span">$h{'word'}</span>
   <p>
   Total Guesses: <b>$h{'total'}</b>
   $time_stat
   <p>
   Your score was <b>$score</b> of a possible <b>$max_score</b> points.
   <br>
~;
   &EndHTML;  
}
__END__
附加的文件
档案类型:txt words.txt (15.1 KB,773视图)
档案类型:txt words_abc_order.txt (17.4 KB,726视图)
档案类型:txt wordguess.txt (13.6 KB,603浏览)

翻译自: https://bytes.com/topic/perl/insights/857707-word-guess-game-similar-hangman

kernel hang

<think>好的,我现在需要处理用户关于内核日志中出现的hang_detect相关信息的提问。用户提供的日志内容是: [ 22.687472] [T1601296] hang_detect HANG_KICK ( 390) [ 22.688081] [T1601296] [Hang_Detect] hang_detect enabled 13 首先,我需要理解这些日志的含义。用户可能是在系统运行过程中遇到了挂起或者响应延迟的问题,系统内的hang_detect机制被触发,生成了这些日志。用户希望了解这些日志的具体含义以及可能的原因和解决方法。 接下来,我要分析日志的各个部分。时间戳是22.687472和22.688081,说明这两个事件发生得非常接近。T1601296可能代表线程ID,但需要确认是否内核中的线程编号通常以T开头。不过,更可能的是,这里的T代表任务(Task),后面的数字是任务或进程的ID。 hang_detect HANG_KICK (390):这里的关键词是hang_detect和HANG_KICK。HANG_KICK可能表示系统检测到了某个任务或进程的挂起,并触发了某种机制(比如踢出或重启)。括号中的390可能是一个错误代码、计数器或者标识符,需要进一步查阅相关内核文档或代码。 第二行的[Hang_Detect] hang_detect enabled 13:这里提到hang_detect被启用,数值13可能代表检测器的实例、参数配置或者某种状态码。需要确认13是否对应特定的配置选项或阈值。 接下来,我需要考虑用户可能的背景。用户可能有一定的技术背景,了解系统日志的基本结构,但可能不熟悉特定的内核机制,如hang_detect。用户可能遇到了系统不稳定或任务挂起的问题,希望通过这些日志找到原因和解决方案。 用户的需求不仅仅是了解日志的含义,更想知道这些日志出现的原因、可能的后果以及如何解决。因此,回答需要包括以下几点: 1. 日志各部分的解释。 2. hang_detect机制的作用。 3. 触发HANG_KICK的可能原因。 4. 数值390和13的可能含义。 5. 解决方法和调试步骤。 需要确保回答准确,避免测,特别是关于数值的具体含义,如果无法确定,应建议用户查阅相关内核文档或代码,或者使用调试工具进一步分析。 同时,用户之前的提问涉及内核线程创建的问题,这次的问题可能相关,可能是同一系统下的不同日志,需要检查是否有共同的原因,比如资源不足或驱动问题。 可能的原因包括: - 硬件问题(如CPU过热、内存故障) - 驱动或内核模块缺陷 - 资源竞争或死锁 - 系统负载过高导致任务无法及时调度 在回答中,需要建议用户检查系统资源使用情况,查看其他相关日志,使用工具如dmesg、ftrace进行调试,检查是否有最近的系统更新或驱动更改,以及如何配置hang_detect的相关参数。 需要确保语言清晰,结构合理,分点说明,便于用户理解和操作。</think>### **内核日志 `hang_detect` 信息解析** 你提供的日志片段表明系统触发了**任务挂起检测(hang_detect)机制**,通常与内核任务长时间未响应或卡死有关。以下是详细分析: --- #### **1. 日志逐行解释** - **`[T1601296] hang_detect HANG_KICK (390)`** - **`T1601296`**:内核任务的唯一标识符(`T` 表示任务,`1601296` 为任务ID)。 - **`hang_detect`**:内核的**任务挂起检测模块**,用于监控关键任务是否在规定时间内完成。 - **`HANG_KICK`**:检测到任务挂起后触发的动作(如重启任务、触发错误处理)。 - **`390`**:可能表示**挂起阈值**(单位可能是毫秒或检测周期次数)或**错误代码**,需结合内核版本和代码确认。 - **`[Hang_Detect] hang_detect enabled 13`** - **`enabled 13`**:表示`hang_detect`机制已启用,`13`可能是: - **检测实例的编号**(例如监控第13个任务或模块)。 - **配置参数**(如超时时间、检测模式)。 - **调试级别**(日志详细程度)。 --- #### **2. `hang_detect` 机制的作用** - **核心功能**:监控关键内核任务(如调度器、中断处理、驱动工作队列)是否在规定时间内完成任务。 - **触发条件**: - 任务因死锁、优先级反转、硬件故障等原因无法释放CPU。 - 任务因代码缺陷(如无限循环)无法退出。 - **响应动作**: - 记录错误日志(`HANG_KICK`)。 - 尝试恢复任务(如发送信号、重置硬件)。 - 触发内核崩溃(Panic)或重启(取决于配置)。 --- #### **3. 常见原因分析** 根据日志内容,可能的问题方向包括: ##### **(1)任务执行超时** - **硬件资源瓶颈**: - CPU被高优先级任务(如中断处理)占满,导致`T1601296`无法调度。 - 内存带宽不足或I/O延迟过高,任务等待资源超时。 - **软件缺陷**: - 任务代码中存在**死锁**(如自旋锁未释放)。 - 任务函数进入**无限循环**(未正确处理边界条件)。 ##### **(2)驱动或内核模块问题** - 驱动中的硬件操作(如传感器读写)因超时未返回。 - 内核模块未正确处理中断信号或异步事件。 ##### **(3)硬件异常** - 外设(如GPU、NPU)未响应,导致关联任务阻塞。 - 内存损坏或总线错误影响任务执行。 --- #### **4. 调试与解决方法** ##### **(1)定位挂起任务** - **通过任务ID查找任务信息**: ```bash # 假设系统支持,查看任务详情 cat /proc/1601296/status ps -eLF | grep 1601296 ``` - 确认任务是内核线程(如`kworker`)还是用户进程。 ##### **(2)分析关联日志** - 使用`dmesg -T`查看完整内核日志,搜索以下关键词: - `HANG_KICK` - `soft lockup`(软死锁) - `hardware error`(硬件错误) ##### **(3)启用内核调试工具** - **检测软死锁**: ```bash # 启用软死锁检测 echo 1 > /proc/sys/kernel/softlockup_panic ``` - **使用`ftrace`跟踪任务调度**: ```bash echo function > /sys/kernel/debug/tracing/current_tracer echo 'schedule' > /sys/kernel/debug/tracing/set_ftrace_filter echo 1 > /sys/kernel/debug/tracing/tracing_on ``` ##### **(4)检查硬件状态** - 通过`smartctl`(硬盘)、`mcelog`(CPU/内存错误)排查硬件故障。 - 监控CPU温度、电压是否异常(如使用`lm-sensors`)。 --- #### **5. 示例解决方案** - **若为驱动问题**: - 更新问题驱动(如通过`dmesg`确认驱动名称)。 - 在驱动代码中添加超时处理和错误恢复逻辑。 - **若为硬件资源争用**: - 调整任务优先级(`sched_setscheduler`)。 - 优化高负载任务的资源分配(如绑定CPU核)。 --- ### **总结** 日志 `hang_detect HANG_KICK (390)` 表明系统检测到任务 `T1601296` 未在规定时间内完成,可能由死锁、硬件故障或驱动缺陷导致。建议通过以下步骤排查: 1. 确认任务类型(内核线程/用户进程)。 2. 检查关联的内核日志和硬件状态。 3. 使用调试工具跟踪任务调度与资源使用。 4. 更新或修复相关驱动/内核模块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值