Love Sun

C++

2038年问题

前言 在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作。所有使用POSIX时间表示时间的程序都将受其影响,因为它们的时间起点是格林尼治时间1970年1月1日0时0分0秒(这个时间名叫 the Unix Epoch),它们用the Unix Epoch经过的秒数(忽略闰秒)来表示时间。这种时间表示法在类Unix(Unix-like)操作系统上是一个标准,并会影响以其C编程语言开发给其他大部份操作系统使用的软件。在大部分的32位操作系统上,此“time_t”数据模式使用一个有符号32位整数(signed int32)存储计算的秒数。依照此“time_t”标准,在此格式能被表示的最后时间是第2147483647秒(代表格林尼治时间2038年1月19日凌晨03:14:07)。下一秒,即格林尼治时间2038年1月19日凌晨03:14:08,由于32位整型溢出,时间将会被“绕回”(wrap around)成一个负数,变成了第 -2147483648 秒(代表格林尼治时间1901年12月13日20:45:52),造成应用程序发生严重的时间错误,而无法运行。 正文 也许大家都已经知道计算机的2000年问题是什么概念,但是什么时候又冒出来一个2038年问题的呢? 用C语言编制的程序不会碰到2000年问题,但是会有2038年问题。这是因为,大多数C语言程序都使用到一个叫做“标准时间库”的程序库,这个时间库用一个标准的4字节也就是32位的形式来储存时间信息。 当初设计的时候,这个4字节的时间格式把1970年1月1日凌晨0时0分0秒(这个时间名叫 the Unix Epoch)作为时间起点,这时的时间值为0。以后所有的时间都是从这个时间开始一秒一秒累积得来的。 比方说如果时间已经累积到了919642718这个数值,就是说这时距离 the Unix Epoch已经过去了919642718秒,换算一下就应该是1999年2月21日16时18分38秒。 这样计算时间的好处在于,把任意两个时间值相减之后,就可以很迅速地得到这两个时间之间相差的秒数,然后你可以利用别的程序把它换算成明白易懂的年月日时分秒的形式。 要是你曾经读过一点儿关于计算机方面的书,你就会知道一个4字节也就是32位的存储空间的最大值是2147483647,请注意!2038年问题的关键也就在这里———当时间一秒一秒地跳完2147483647那惊心动魄的最后一秒后,你猜怎么样? 答案是,它就会转为负数也就是说时间无效。那一刻的准确的时间为2038年1月19日星期二凌晨03:14:07,之后所有用到这种“标准时间库”的C语言程序都会碰到时间计算上的麻烦。 这就是2038年问题。 但是大家也不用太过紧张。2038年问题比千年虫(the Millennium bug)问题解决起来相对要容易一些,只要给那些程序换一个新版本的“标准时间库”就可以了,比如说,改用8字节64位的形式来存储时间。这样做并不怎么费事,因为在C程序中“标准时间库”是相对独立的一个部分,里面的时间表达都有自己的一套时间类型和参数(而在碰到Y2K的那些大型主机中,时间格式大都没有一)。 说到这里,一些冰雪聪明的菜鸟DDMM们应该可以联想到,WindowsNT用的是64位操作平台,它的开始时间是1601年1月1日———但是它每过1个纳秒就跳一下,因此,WindowsNT它会碰到的是2184年问题…… 而在一些用64位来表示时间的平台上,例如DigitalAlpha、SGI、Sparc等等,想要看到它们的时间出错你得等到天荒地老———那大概是2920亿年。到那时,位于猎户座旋臂的太阳,已经是黑矮星或暗黑物质,猎户座旋臂已经被重力波震断,银河系大概则已经变成小型似星体了。 所以,给那些准备攒机的菜鸟DD一个建议,除非您想要把资料流传给下一个宇宙,一台64位的电脑已经足够。 总之,32位的最后时间是2038年1月19日03:14:07,星期二。 64位的最后时间约2900亿年后的292,277,026,596年12月4日15:30:08,星期日。 refer to:http://blog.csdn.net/linyt/article/details/52728910

Linux下,多线程程序死循环问题调试

当你的软件在某个时刻停止服务,CPU占用达到100%+,这种问题一个可能的原因是产生了死循环,假设程序某处存在潜在的死循环,并在某种条件下会引发,本文以一个示例来定位出现死循环的位置。 当程序某处存在死循环,通常定位问题及缩小范围的方法是,在可疑的代码处加log,或者注释掉可疑代码,这对于容易重现问题的程序来说还好,但对于“偶尔”才会产生问题程序却很难调试,因为我们很难重现程序故障。本文所述的调试过程正是在这种情况下,假设问题已经出现,我们要求环境保护现场,即出问题的程序还在运行中。 1.我们首先要知道是哪个线程出了问题: 首先查一下出问题进程的pid,例如

然后top命令查看线程信息:

从上面可以看出,出问题线程PID为11073 2.接下来,我们用gdb来attach目标进程 执行:

在gdb中,列出线程状态:

gdb已经列出了各线程正在执行的函数,我们需要更多信息,记住11073对应的行首标号,这是gdb为线程分配的id,这里为2,然后执行切换:

bt一下:

来看一下101行的代码:

现在我们定位到了出问题的代码位置,这里的循环只用来演示的。 最后别忘了detach refer to:http://www.cppblog.com/elva/archive/2010/08/02/121943.html

C/C++获取进程信息

Taking a Snapshot and Viewing Processes The following simple console application obtains a list of running processes. First, the GetProcessList function takes a snapshot of currently executing processes in the system using CreateToolhelp32Snapshot, and then it walks through the list recorded in the snapshot using Process32First and Process32Next. For each process in turn, GetProcessList calls the ListProcessModules function which is described in Traversing the Module List, and the ListProcessThreads function which is described in Traversing the Thread List. A simple error-reporting function, printError, displays the reason for any failures, which usually result from security restrictions.