<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>益友网 &#187; Linux技巧</title>
	<atom:link href="http://www.1uu2.com/archives/category/linux-jiqiao/feed" rel="self" type="application/rss+xml" />
	<link>http://www.1uu2.com</link>
	<description>Linux之友</description>
	<lastBuildDate>Sat, 07 Jan 2012 09:01:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Get Linux 0.1发布 帮助Windows用户认识Linux</title>
		<link>http://www.1uu2.com/archives/2491</link>
		<comments>http://www.1uu2.com/archives/2491#comments</comments>
		<pubDate>Sat, 07 Jan 2012 09:00:50 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>
		<category><![CDATA[Get Linux]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2491</guid>
		<description><![CDATA[Get Linux是一个小型的Windows工具，它可以帮助用户找出多达100种Linux发行版的下载和安装方法，使用非常简单，只需要在列表中找到自己中意的版本然后选择32还是64位就可以开始下载了，同时这款软件还会提供不同Linux的图像和视频，帮助用户转移到Linux平台。 下载:Get Linux 0.1 via:http://www.cnbeta.com/articles/168282.htm]]></description>
			<content:encoded><![CDATA[<p>Get Linux是一个小型的Windows工具，它可以帮助用户找出多达100种Linux发行版的下载和安装方法，使用非常简单，只需要在列表中找到自己中意的版本然后选择32还是64位就可以开始下载了，同时这款软件还会提供不同Linux的图像和视频，帮助用户转移到Linux平台。<span id="more-2491"></span></p>
<p><img src="http://www.1uu2.com/wp-content/uploads/auto_save_image/2012/01/0901006Y8.png" alt="http://www.1uu2.com/wp-content/uploads/auto_save_image/2012/01/0901006Y8.png" /></p>
<p><img src="http://www.1uu2.com/wp-content/uploads/auto_save_image/2012/01/090106ckA.gif" alt="" /><strong>下载:</strong><a href="http://www.downloadcrew.com/article/26552-get_linux" target="_blank">Get Linux 0.1</a></p>
<p>via:<a href="http://www.cnbeta.com/articles/168282.htm" target="_blank">http://www.cnbeta.com/articles/168282.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2491/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux操作系统进程-进程的退出</title>
		<link>http://www.1uu2.com/archives/2475</link>
		<comments>http://www.1uu2.com/archives/2475#comments</comments>
		<pubDate>Thu, 29 Dec 2011 02:27:26 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>
		<category><![CDATA[进程]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2475</guid>
		<description><![CDATA[void _exit(int status) 注意点： 1.status表明了进程终止时的状态。当子进程使用_exit()后，父进程如果在用wait()等待子进程，那么wait()将会返回status状态，注意只有status的低8位(0~255)会返回给父进程。通常，我们使用0，表示进程成功返回，非负值表示进程不成功返回。但是，这种约定不是强制的，每个应用程序都可以自己指定。 2.虽然返回值可以是0~255，但是我们通常使用0~128。因为在shell编程中，如果一个进程被信号打断，shell会返回128+信号编号。在shell中，这两个值是没有区别的(都是当做进程返回值)，如果我们进程中使用了128~255，那么就无法区别到底是信号打断还是进程自己退出了。 void exit(int status) 注意点： 1.在exit()调用后，退出处理函数(exit handler)首先被执行(这些函数使用atexit()和on_exit()注册)。 2.stdio流缓冲区被刷新。(还有其他资源的清理) 3.最后一步才是调用_exit()退出。 4.在main函数中最后调用return n和调用exit()是相同的作用。如果在main函数最后调用return或不调用任何退出函数，调用main的运行时函数会自动的调用exit()，但是status会变得不确定(在C89中，status可能会是栈中的某个值，或CPU寄存器中的某个值，这要看编译器是怎么使用的。在C99中，要求status必须是0)。 注册退出处理函数 在程序退出之前，我们都会主动地做一些清理的动作，比如把程序缓冲区的数据保存在文件上。通常的做法是在exit()之前，调用一些清理函数。但这种做法的弊端是，在每个可能退出的地方都写上一大堆相同的代码。另外一种方式就是让程序中所有可能退出的点，都全部集中在一个地方处理。这样做的问题是会出现大量的判断是否成功语句，让代码显得不清晰。Linux提供了下面的两个函数来解决这种问题，把所有的清理函数注册进lib库中，当任意一处调用exit()时，系统会自动的调用注册上的清理函数。 int atexit(void (*func)(void)) 注意点： 1.可以注册多个函数，并且一个函数也可多次注册。当要调用它们时，是按照FILO顺序执行的。 2.函数注册后，没办法取消注册。 3.清理函数中调用exit()的行为，在SUSv3中没有定义。在linux中，会继续执行剩下的清理函数。但在某些系统中，可能出现死循环。 4.子进程会继承父进程中的清理函数。 #define _BSD_SOURCE int on_exit(void (*func)(int, void *)， void *arg) 注意点： 1. on_exit()是atexit()的改良版。在on_exit()中，可以通过func中的int参数知道exit()的退出状态;同一个func可以根据arg的不同，执行不同的代码。 2.唯一的缺点是并不是每个系统都实行了改函数。 代码分析 int main(int argc, char *argv[]) { printf(“Hello world\n”); Write(STDOUT_FILENO, “CC\n”， 3); if (fork() == -1) [...]]]></description>
			<content:encoded><![CDATA[<p>void _exit(int status)</p>
<p>注意点：</p>
<p>1.status表明了进程终止时的状态。当子进程使用_exit()后，父进程如果在用wait()等待子进程，那么wait()将会返回status状态，注意只有status的低8位(0~255)会返回给父进程。通常，我们使用0，表示进程成功返回，非负值表示进程不成功返回。但是，这种约定不是强制的，每个应用程序都可以自己指定。<span id="more-2475"></span></p>
<p>2.虽然返回值可以是0~255，但是我们通常使用0~128。因为在shell编程中，如果一个进程被信号打断，shell会返回128+信号编号。在shell中，这两个值是没有区别的(都是当做进程返回值)，如果我们进程中使用了128~255，那么就无法区别到底是信号打断还是进程自己退出了。</p>
<p>void exit(int status)</p>
<p>注意点：</p>
<p>1.在exit()调用后，退出处理函数(exit handler)首先被执行(这些函数使用atexit()和on_exit()注册)。</p>
<p>2.stdio流缓冲区被刷新。(还有其他资源的清理)</p>
<p>3.最后一步才是调用_exit()退出。</p>
<p>4.在main函数中最后调用return n和调用exit()是相同的作用。如果在main函数最后调用return或不调用任何退出函数，调用main的运行时函数会自动的调用exit()，但是status会变得不确定(在C89中，status可能会是栈中的某个值，或CPU寄存器中的某个值，这要看编译器是怎么使用的。在C99中，要求status必须是0)。</p>
<p>注册退出处理函数</p>
<p>在程序退出之前，我们都会主动地做一些清理的动作，比如把程序缓冲区的数据保存在文件上。通常的做法是在exit()之前，调用一些清理函数。但这种做法的弊端是，在每个可能退出的地方都写上一大堆相同的代码。另外一种方式就是让程序中所有可能退出的点，都全部集中在一个地方处理。这样做的问题是会出现大量的判断是否成功语句，让代码显得不清晰。Linux提供了下面的两个函数来解决这种问题，把所有的清理函数注册进lib库中，当任意一处调用exit()时，系统会自动的调用注册上的清理函数。</p>
<p>int atexit(void (*func)(void))</p>
<p>注意点：</p>
<p>1.可以注册多个函数，并且一个函数也可多次注册。当要调用它们时，是按照FILO顺序执行的。</p>
<p>2.函数注册后，没办法取消注册。</p>
<p>3.清理函数中调用exit()的行为，在SUSv3中没有定义。在linux中，会继续执行剩下的清理函数。但在某些系统中，可能出现死循环。</p>
<p>4.子进程会继承父进程中的清理函数。</p>
<p>#define _BSD_SOURCE</p>
<p>int on_exit(void (*func)(int, void *)， void *arg)</p>
<p>注意点：</p>
<p>1. on_exit()是atexit()的改良版。在on_exit()中，可以通过func中的int参数知道exit()的退出状态;同一个func可以根据arg的不同，执行不同的代码。</p>
<p>2.唯一的缺点是并不是每个系统都实行了改函数。</p>
<p>代码分析</p>
<p>int main(int argc, char *argv[])</p>
<p>{</p>
<p>printf(“Hello world\n”);</p>
<p>Write(STDOUT_FILENO, “CC\n”， 3);</p>
<p>if (fork() == -1)</p>
<p>exit(1);</p>
<p>exit(0);</p>
<p>}</p>
<p>当在终端执行该程序时，输出入下：</p>
<p>Hello World</p>
<p>CC</p>
<p>当把文字输出到文件时，文件中保存的文字如下：</p>
<p>CC</p>
<p>Hello World</p>
<p>Hello World</p>
<p>分析：当把文字输出到终端时，stdio函数组是按行输出。而输出到文件时，是按照块输出。也就是说，在输出到文件时，printf()函数把”Hello World\n”输入进用户stdio缓冲区，但是没有达到输出块的大小。write函数直接把“CC\n”输出到内核缓冲区，而不是用户进程的缓冲区。接下来fork()出一个子进程，子进程的用户缓冲区是拷贝父进程的，也就是说在子进程中的stdio缓冲区中也存在一个”Hello World\n”，但是内核缓冲区是不会拷贝的。CC出现在Hello World前面是因为执行完write()后，CC已近在内核缓冲区中，而printf()后“Hello World”还在用户stdio缓冲区中，直到执行了exit()，才把“Hello World”刷新到内核缓冲区中。</p>
<p>来源:中国IT实验室  佚名</p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2475/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何克服Unix到Linux迁移的常见问题？</title>
		<link>http://www.1uu2.com/archives/2472</link>
		<comments>http://www.1uu2.com/archives/2472#comments</comments>
		<pubDate>Thu, 29 Dec 2011 02:24:51 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>
		<category><![CDATA[Linux迁]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[X86]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2472</guid>
		<description><![CDATA[经过了最初的测试后，你已经打算从Unix迁移到Linux上了，现在您应该注意哪些主要的问题呢?在Unix向Linux迁移的过程中通常会遇到一些什么样的问题或错误?您应该向谁求助?好的规划完全能让您避开这些问题。 确定可能的硬件挑战 在考虑迁移的过程中，最应该注意的问题就是平台依赖性，特别是从RISC迁移到X86平台。这时候，Endianess就能派上用场。 Endianess是指用于显示数据的内存排序。它规定数据元素和字节如何在内存中存储。您可能会遇到的问题就是在x86的计算机系统中很少使用Endian,但是RISC系统中却大量的使用Endian.如果您从RISC迁移到x86,反之亦然，您将需要修改迁移代码。在评估阶段，您就应该清楚的意识到这些问题。 一些厂商已经想出了一些颇有创意的办法去解决这些问题。例如： IBM开发了PowerVM Lx86,这是一个中型规模的虚拟化引擎的部件。它使用特别的软件自动把指令转换成电压信号，从而不用在本机上进行编译。 虽然在Linux运行在IBM Power平台之前，Linux必须在本地运行并重新编译。当然，这个已经不再是个问题。转换器作为PowerVM Lx86的一部分，能把x86 Linux指令很轻松地转换成电压 Linux指令，只需三步：解码、优化和生产代码。这非常适用于Web应用程序，因为有大量重复工作，因为这些频繁使用的代码已经在内存中，所以无需再重新转换。 另一个需要考虑的方面是应用程序需要的内核扩展和设备驱动。为应用程序找到合适的内核扩展和设备驱动并不是一件容易的事情，其中部分原因是大多数的内核API并不严格遵从标准。API指令、参数的数量和调用到内核扩展的过程在新平台上都会有所不同。 另一个要考虑的是需要内核扩展和设备驱动程序的应用程序。这些都不是容易的候选支持，这一部分是因为大多数的内核API不遵循任何严格的标准。 API调用的参数的数量和加载到内核扩展的过程中将所有的功能不同的新的平台上。 评估应用程序对于Linux的适用性和有效性 绝大多数的商业和网络应用程序都能在Linux上运行。但是有效性则是另一回事。 虽然今天几乎所有的生产商都已经把他们的Unix应用程序移到Linux上，但是关键是，在考虑迁移之前，如何确保现有的应用程序已经能很好地支持了这种可能的迁移。否则，您将不得不陷入自己去迁移这些应用程序的困境。对于内部应用程序的开发，您需要的是一个强大的开发团队来帮助完成应用程序的迁移。 向有过此种经验的同事咨询。了解一下您的应用程序迁移到Linux会如何。并且核实这些应用程序现在的运行情况。不用担心，请大胆地向您的生产商请求帮助。Red Hat和SUSE都提供相应的服务帮助您完成移植。 关于部署的问题和错误 当你在做迁移的时候，你可能会遇到什么样的错误或问题?首先，适当的测试非常必要。在迁移过程中，任何一件事情都可能出错，所以在生成环境之前，应该搭建一个测试和实验环境来发现和经历问题。 几年前，我的小组看似非常顺利地完成了一个重要的迁移，但是不久就开始接到电话说工资管理系统不能正常运行。这有点出乎我们的意料，之前我们进行了系统的单元测试、用户测试以及UAT测试。事实证明，问题不是出在迁移方面，而是因为一些PC客户端不能很好的与旧版本的Oracle客户端兼容。 还有一个问题是有关Unix外壳脚本。有人可能想当然的认为，Unix外壳脚本在Linux平台上也一样能很好地运行。不幸的是，这种假设不成立。 任何一个与应用程序有关的Unix脚本都需要仔细测试。Linux的标准外壳是使用Bash外壳，它是建立在Unix最初的Bourne外壳。然而，在我们的例子里，Unix使用的是Korn外壳。所以，肯定有些功能不能正确工作。因此，有必要假设您的外壳脚本在新平台下可能不能正常工作。请测试每一个您需要的外壳脚本。 获取技术支持 技术支持取决于您IT部门的大小和员工的经验。您是否有几个无所不能、经验丰富的Linux管理员呢?或者他们也许是Unix管理员，但是他们是否已经做好准备去接受Linux呢? 技术支持程度取决于您所用于的环境类型。您是否正在运行那些每分钟的故障能导致公司数万美元损失的系统呢 ,如：CRM系统或者工资系统? 来自于生产商的技术支持也是非常重要。Red Hat和Novell都提供24/7的技术支持。一些Unix硬件生产商，如IBM,也提供自己的Linux技术支持。 如果可能，请从您的硬件提供商那里获得技术支持。而且，这对您从操作系统提供商哪里获得技术支持不会产生任何不利的影响。最后还是那句话，您需要仔细考虑您的组织中，系统停机带来的经济影响和您员工的经验和能力。 来源:TechTarget中国]]></description>
			<content:encoded><![CDATA[<p>经过了最初的测试后，你已经打算从Unix迁移到Linux上了，现在您应该注意哪些主要的问题呢?在Unix向Linux迁移的过程中通常会遇到一些什么样的问题或错误?您应该向谁求助?好的规划完全能让您避开这些问题。<span id="more-2472"></span></p>
<p><strong>确定可能的硬件挑战</strong></p>
<p>在考虑迁移的过程中，最应该注意的问题就是平台依赖性，特别是从RISC迁移到X86平台。这时候，Endianess就能派上用场。</p>
<p>Endianess是指用于显示数据的内存排序。它规定数据元素和字节如何在内存中存储。您可能会遇到的问题就是在x86的计算机系统中很少使用Endian,但是RISC系统中却大量的使用Endian.如果您从RISC迁移到x86,反之亦然，您将需要修改迁移代码。在评估阶段，您就应该清楚的意识到这些问题。</p>
<p>一些厂商已经想出了一些颇有创意的办法去解决这些问题。例如： IBM开发了PowerVM Lx86,这是一个中型规模的虚拟化引擎的部件。它使用特别的软件自动把指令转换成电压信号，从而不用在本机上进行编译。</p>
<p>虽然在Linux运行在IBM Power平台之前，Linux必须在本地运行并重新编译。当然，这个已经不再是个问题。转换器作为PowerVM Lx86的一部分，能把x86 Linux指令很轻松地转换成电压 Linux指令，只需三步：解码、优化和生产代码。这非常适用于Web应用程序，因为有大量重复工作，因为这些频繁使用的代码已经在内存中，所以无需再重新转换。</p>
<p>另一个需要考虑的方面是应用程序需要的内核扩展和设备驱动。为应用程序找到合适的内核扩展和设备驱动并不是一件容易的事情，其中部分原因是大多数的内核API并不严格遵从标准。API指令、参数的数量和调用到内核扩展的过程在新平台上都会有所不同。</p>
<p>另一个要考虑的是需要内核扩展和设备驱动程序的应用程序。这些都不是容易的候选支持，这一部分是因为大多数的内核API不遵循任何严格的标准。 API调用的参数的数量和加载到内核扩展的过程中将所有的功能不同的新的平台上。</p>
<p><strong>评估应用程序对于Linux的适用性和有效性</strong></p>
<p>绝大多数的商业和网络应用程序都能在Linux上运行。但是有效性则是另一回事。</p>
<p>虽然今天几乎所有的生产商都已经把他们的Unix应用程序移到Linux上，但是关键是，在考虑迁移之前，如何确保现有的应用程序已经能很好地支持了这种可能的迁移。否则，您将不得不陷入自己去迁移这些应用程序的困境。对于内部应用程序的开发，您需要的是一个强大的开发团队来帮助完成应用程序的迁移。</p>
<p>向有过此种经验的同事咨询。了解一下您的应用程序迁移到Linux会如何。并且核实这些应用程序现在的运行情况。不用担心，请大胆地向您的生产商请求帮助。Red Hat和SUSE都提供相应的服务帮助您完成移植。</p>
<p><strong>关于部署的问题和错误</strong></p>
<p>当你在做迁移的时候，你可能会遇到什么样的错误或问题?首先，适当的测试非常必要。在迁移过程中，任何一件事情都可能出错，所以在生成环境之前，应该搭建一个测试和实验环境来发现和经历问题。</p>
<p>几年前，我的小组看似非常顺利地完成了一个重要的迁移，但是不久就开始接到电话说工资管理系统不能正常运行。这有点出乎我们的意料，之前我们进行了系统的单元测试、用户测试以及UAT测试。事实证明，问题不是出在迁移方面，而是因为一些PC客户端不能很好的与旧版本的Oracle客户端兼容。</p>
<p>还有一个问题是有关Unix外壳脚本。有人可能想当然的认为，Unix外壳脚本在Linux平台上也一样能很好地运行。不幸的是，这种假设不成立。</p>
<p>任何一个与应用程序有关的Unix脚本都需要仔细测试。Linux的标准外壳是使用Bash外壳，它是建立在Unix最初的Bourne外壳。然而，在我们的例子里，Unix使用的是Korn外壳。所以，肯定有些功能不能正确工作。因此，有必要假设您的外壳脚本在新平台下可能不能正常工作。请测试每一个您需要的外壳脚本。</p>
<p><strong>获取技术支持</strong></p>
<p>技术支持取决于您IT部门的大小和员工的经验。您是否有几个无所不能、经验丰富的Linux管理员呢?或者他们也许是Unix管理员，但是他们是否已经做好准备去接受Linux呢?</p>
<p>技术支持程度取决于您所用于的环境类型。您是否正在运行那些每分钟的故障能导致公司数万美元损失的系统呢 ,如：CRM系统或者工资系统?</p>
<p>来自于生产商的技术支持也是非常重要。Red Hat和Novell都提供24/7的技术支持。一些Unix硬件生产商，如IBM,也提供自己的Linux技术支持。</p>
<p>如果可能，请从您的硬件提供商那里获得技术支持。而且，这对您从操作系统提供商哪里获得技术支持不会产生任何不利的影响。最后还是那句话，您需要仔细考虑您的组织中，系统停机带来的经济影响和您员工的经验和能力。</p>
<p>来源:TechTarget中国</p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2472/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux平台用C++实现信号量同步线程</title>
		<link>http://www.1uu2.com/archives/2465</link>
		<comments>http://www.1uu2.com/archives/2465#comments</comments>
		<pubDate>Tue, 27 Dec 2011 16:20:46 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2465</guid>
		<description><![CDATA[使用Linux平台上现有的信号量sem_t相关的一组API，可以方便地进行线程同步。现在用pthread_mutex_t和pthread_cond_t相关的一组API实现信号量机制。这组API包括：pthread_mutex_init，pthread_cond_init，pthread_mutex_lock，pthread_cond_signal，pthread_mutex_unlock，pthread_cond_wait，pthread_cond_timedwait，pthread_cond_destroy和pthread_mutex_destroy，下边，是封装的信号量类，以及测试代码。使用VS2005编辑，在虚拟机 Fedora 13中编译，测试通过。 MySemaphore.h view plain #ifndef Semaphore_Header #define Semaphore_Header #include #include #include #include using namespace std; //&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; class CSemaphoreImpl { protected: CSemaphoreImpl(int n, int max); ~CSemaphoreImpl(); void SetImpl(); void WaitImpl(); bool WaitImpl(long lMilliseconds); private: volatile int m_n; int m_max; pthread_mutex_t m_mutex; pthread_cond_t m_cond; }; inline void CSemaphoreImpl::SetImpl() { if (pthread_mutex_lock(&#38;m_mutex)) cout&#60;&#60;&#8221;cannot signal semaphore (lock)&#8221;&#60; [...]]]></description>
			<content:encoded><![CDATA[<p>使用Linux平台上现有的信号量sem_t相关的一组API，可以方便地进行线程同步。现在用pthread_mutex_t和pthread_cond_t相关的一组API实现信号量机制。这组API包括：pthread_mutex_init，pthread_cond_init，pthread_mutex_lock，pthread_cond_signal，pthread_mutex_unlock，pthread_cond_wait，pthread_cond_timedwait，pthread_cond_destroy和pthread_mutex_destroy，下边，是封装的信号量类，以及测试代码。使用VS2005编辑，在虚拟机 Fedora 13中编译，测试通过。<span id="more-2465"></span></p>
<p>MySemaphore.h</p>
<p>view plain</p>
<p>#ifndef Semaphore_Header</p>
<p>#define Semaphore_Header</p>
<p>#include</p>
<p>#include</p>
<p>#include</p>
<p>#include</p>
<p>using namespace std;</p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>class CSemaphoreImpl</p>
<p>{</p>
<p>protected:</p>
<p>CSemaphoreImpl(int n, int max);</p>
<p>~CSemaphoreImpl();</p>
<p>void SetImpl();</p>
<p>void WaitImpl();</p>
<p>bool WaitImpl(long lMilliseconds);</p>
<p>private:</p>
<p>volatile int m_n;</p>
<p>int m_max;</p>
<p>pthread_mutex_t m_mutex;</p>
<p>pthread_cond_t m_cond;</p>
<p>};</p>
<p>inline void CSemaphoreImpl::SetImpl()</p>
<p>{</p>
<p>if (pthread_mutex_lock(&amp;m_mutex))</p>
<p>cout&lt;&lt;&#8221;cannot signal semaphore (lock)&#8221;&lt;</p>
<p>if (m_n &lt; m_max)</p>
<p>{</p>
<p>++m_n;</p>
<p>}</p>
<p>else</p>
<p>{</p>
<p>pthread_mutex_unlock(&amp;m_mutex);</p>
<p>cout&lt;&lt;&#8221;cannot signal semaphore: count would exceed maximum&#8221;&lt;&lt;&#8221; m_n = &#8220;&lt;</p>
<p>}</p>
<p>pthread_mutex_unlock(&amp;m_mutex);</p>
<p>}</p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>/*</p>
<p>信号量同步机制</p>
<p>信号量提供一个计数值，可以进行原子操作。V 将计数值加1，使得</p>
<p>等待该信号量的线程可以被调用(调用Set())，P 将计数值减1，使</p>
<p>当前线程被挂起，进行睡眠(调用Wait())。</p>
<p>当信号量的计数值被初始化为0时，调用P操作，将挂起当前线程。</p>
<p>当信号量被激活，即调用V操作后，被挂起的线程就有机会被重新调度了。</p>
<p>*/</p>
<p>class CMySemaphore: private CSemaphoreImpl</p>
<p>{</p>
<p>public:</p>
<p>/*</p>
<p>创建一个信号量，信号量计数值当前值为参数n，最大值为max。</p>
<p>如果只有n，则n必须大于0;如果同时有n和max,则n必须不小</p>
<p>于0，且不大于max</p>
<p>*/</p>
<p>CMySemaphore(int n);</p>
<p>CMySemaphore(int n, int max);</p>
<p>/*</p>
<p>销毁一个信号量</p>
<p>*/</p>
<p>~CMySemaphore();</p>
<p>/*</p>
<p>对信号量计数值做加1动作，信号量变为有信号状态，使得</p>
<p>另一个等待该信号量的线程可以被调度</p>
<p>*/</p>
<p>void Set();</p>
<p>/*</p>
<p>对信号量计数值做减1动作，信号量变为无信号状态。若</p>
<p>计数值变得大于0时，信号量才会变为有信号状态。</p>
<p>*/</p>
<p>void Wait();</p>
<p>/*</p>
<p>在给定的时间间隔里等待信号量变为有信号状态，若成功，</p>
<p>则将计数值减1，否则将发生超时。</p>
<p>*/</p>
<p>void Wait(long lMilliseconds);</p>
<p>/*</p>
<p>在给定的时间间隔里等待信号量变为有信号状态，若成功，</p>
<p>则将计数值减1，返回true;否则返回false。</p>
<p>*/</p>
<p>bool TryWait(long lMilliseconds);</p>
<p>private:</p>
<p>CMySemaphore();</p>
<p>CMySemaphore(const CMySemaphore&amp;);</p>
<p>CMySemaphore&amp; operator = (const CMySemaphore&amp;);</p>
<p>};</p>
<p>inline void CMySemaphore::Set()</p>
<p>{</p>
<p>SetImpl();</p>
<p>}</p>
<p>inline void CMySemaphore::Wait()</p>
<p>{</p>
<p>WaitImpl();</p>
<p>}</p>
<p>inline void CMySemaphore::Wait(long lMilliseconds)</p>
<p>{</p>
<p>if (!WaitImpl(lMilliseconds))</p>
<p>cout&lt;&lt;&#8221;time out&#8221;&lt;</p>
<p>}</p>
<p>inline bool CMySemaphore::TryWait(long lMilliseconds)</p>
<p>{</p>
<p>return WaitImpl(lMilliseconds);</p>
<p>}</p>
<p>#endif</p>
<p>MySemaphore.cpp</p>
<p>view plain</p>
<p>#include &#8220;MySemaphore.h&#8221;</p>
<p>#include</p>
<p>CSemaphoreImpl::CSemaphoreImpl(int n, int max): m_n(n), m_max(max)</p>
<p>{</p>
<p>assert (n &gt;= 0 &amp;&amp; max &gt; 0 &amp;&amp; n &lt;= max);</p>
<p>if (pthread_mutex_init(&amp;m_mutex, NULL))</p>
<p>cout&lt;&lt;&#8221;cannot create semaphore (mutex)&#8221;&lt;</p>
<p>if (pthread_cond_init(&amp;m_cond, NULL))</p>
<p>cout&lt;&lt;&#8221;cannot create semaphore (condition)&#8221;&lt;</p>
<p>}</p>
<p>CSemaphoreImpl::~CSemaphoreImpl()</p>
<p>{</p>
<p>pthread_cond_destroy(&amp;m_cond);</p>
<p>pthread_mutex_destroy(&amp;m_mutex);</p>
<p>}</p>
<p>void CSemaphoreImpl::WaitImpl()</p>
<p>{</p>
<p>if (pthread_mutex_lock(&amp;m_mutex))</p>
<p>cout&lt;&lt;&#8221;wait for semaphore failed (lock)&#8221;&lt;</p>
<p>while (m_n &lt; 1)</p>
<p>{</p>
<p>//对互斥体进行原子的解锁工作,然后等待状态信号</p>
<p>if (pthread_cond_wait(&amp;m_cond, &amp;m_mutex))</p>
<p>{</p>
<p>pthread_mutex_unlock(&amp;m_mutex);</p>
<p>cout&lt;&lt;&#8221;wait for semaphore failed&#8221;&lt;</p>
<p>}</p>
<p>}</p>
<p>&#8211;m_n;</p>
<p>pthread_mutex_unlock(&amp;m_mutex);</p>
<p>}</p>
<p>bool CSemaphoreImpl::WaitImpl(long lMilliseconds)</p>
<p>{</p>
<p>int rc = 0;</p>
<p>struct timespec abstime;</p>
<p>struct timeval tv;</p>
<p>gettimeofday(&amp;tv, NULL);</p>
<p>abstime.tv_sec = tv.tv_sec + lMilliseconds / 1000;</p>
<p>abstime.tv_nsec = tv.tv_usec*1000 + (lMilliseconds % 1000)*1000000;</p>
<p>if (abstime.tv_nsec &gt;= 1000000000)</p>
<p>{</p>
<p>abstime.tv_nsec -= 1000000000;</p>
<p>abstime.tv_sec++;</p>
<p>}</p>
<p>if (pthread_mutex_lock(&amp;m_mutex) != 0)</p>
<p>cout&lt;&lt;&#8221;wait for semaphore failed (lock)&#8221;&lt;</p>
<p>while (m_n &lt; 1)</p>
<p>{</p>
<p>//自动释放互斥体并且等待m_cond状态,并且限制了最大的等待时间</p>
<p>if ((rc = pthread_cond_timedwait(&amp;m_cond, &amp;m_mutex, &amp;abstime)))</p>
<p>{</p>
<p>if (rc == ETIMEDOUT) break;</p>
<p>pthread_mutex_unlock(&amp;m_mutex);</p>
<p>cout&lt;&lt;&#8221;cannot wait for semaphore&#8221;&lt;</p>
<p>}</p>
<p>}</p>
<p>if (rc == 0) &#8211;m_n;</p>
<p>pthread_mutex_unlock(&amp;m_mutex);</p>
<p>return rc == 0;</p>
<p>}</p>
<p>CMySemaphore::CMySemaphore(int n): CSemaphoreImpl(n, n)</p>
<p>{</p>
<p>}</p>
<p>CMySemaphore::CMySemaphore(int n, int max): CSemaphoreImpl(n, max)</p>
<p>{</p>
<p>}</p>
<p>CMySemaphore::~CMySemaphore()</p>
<p>{</p>
<p>}</p>
<p>下边是测试代码</p>
<p>view plain</p>
<p>// pthread_semaphore.cpp : 定义控制台应用程序的入口点。</p>
<p>//</p>
<p>#include &#8220;MySemaphore.h&#8221;</p>
<p>//创建一个信号量，其计数值当前值为0，最大值为3</p>
<p>CMySemaphore g_MySem(0, 3);</p>
<p>//线程函数</p>
<p>void * StartThread(void *pParam)</p>
<p>{</p>
<p>//休眠1秒，确保主线程函数main中</p>
<p>//创建工作线程下一句g_MySem.Set();先执行</p>
<p>sleep(1);</p>
<p>g_MySem.Wait(); //信号量计数值减1</p>
<p>cout&lt;&lt;&#8221;Do print StartThread&#8221;&lt;</p>
<p>return (void *)0;</p>
<p>}</p>
<p>int main(int argc, char* argv[])</p>
<p>{</p>
<p>pthread_t thread;</p>
<p>pthread_attr_t attr;</p>
<p>assert ( !g_MySem.TryWait(10) );</p>
<p>g_MySem.Set(); //信号量计数值加1</p>
<p>g_MySem.Wait(); //信号量计数值减1</p>
<p>try</p>
<p>{</p>
<p>g_MySem.Wait(100);</p>
<p>cout&lt;&lt;&#8221;must timeout&#8221;&lt;</p>
<p>}</p>
<p>catch (&#8230;)</p>
<p>{</p>
<p>cout&lt;&lt;&#8221;wrong exception&#8221;&lt;</p>
<p>}</p>
<p>g_MySem.Set();</p>
<p>g_MySem.Set();</p>
<p>assert ( g_MySem.TryWait(0) );</p>
<p>g_MySem.Wait();</p>
<p>assert ( !g_MySem.TryWait(10) );</p>
<p>//创建工作线程</p>
<p>pthread_attr_init(&amp;attr);</p>
<p>pthread_attr_setdetachstate(&amp;attr,PTHREAD_CREATE_JOINABLE);</p>
<p>if (pthread_create(&amp;thread,&amp;attr, StartThread,NULL) == -1)</p>
<p>{</p>
<p>cout&lt;&lt;&#8221;StartThread: create failed&#8221;&lt;</p>
<p>}</p>
<p>g_MySem.Set();</p>
<p>//等待线程结束</p>
<p>void *result;</p>
<p>pthread_join(thread,&amp;result);</p>
<p>assert ( !g_MySem.TryWait(10) ); //若将断言中的 ! 去掉，则会发生断言错误</p>
<p>//关闭线程句柄，释放资源</p>
<p>pthread_attr_destroy(&amp;attr);</p>
<p>int iWait;</p>
<p>cin&gt;&gt;iWait;</p>
<p>return 0;</p>
<p>}</p>
<p>编译，运行。可以看到，与Win32平台上的测试结果相同</p>
<p>由此可见，信号量机制很关键的一点就是计数值 m_n。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2465/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux中文简体 Cron计划任务详细讲解</title>
		<link>http://www.1uu2.com/archives/2444</link>
		<comments>http://www.1uu2.com/archives/2444#comments</comments>
		<pubDate>Fri, 25 Nov 2011 04:05:28 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2444</guid>
		<description><![CDATA[cron是一个linux下的定时执行工具，可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务，但它不自动起来，可以用以下的方法启动、关闭这个服务: /sbin/service crond start //启动服务 /sbin/service crond stop //关闭服务 /sbin/service crond restart //重启服务 /sbin/service crond reload //重新载入配置 你也可以将这个服务在系统启动的时候自动启动: 在/etc/rc.d/rc.local这个脚本的末尾加上: /sbin/service crond start 现在Cron这个服务已经在进程里面了，我们就可以用这个服务了，Cron服务提供以下几种接口供大家使用: 1.直接用crontab命令编辑 cron服务提供crontab命令来设定cron服务的，以下是这个命令的一些参数与说明: crontab -u //设定某个用户的cron服务，一般root用户在执行这个命令的时候需要此参数 crontab -l //列出某个用户cron服务的详细内容 crontab -r //删除没个用户的cron服务 crontab -e //编辑某个用户的cron服务 比如说root查看自己的cron设置:crontab -u root -l 再例如，root想删除fred的cron设置:crontab -u fred -r 在编辑cron服务时，编辑的内容有一些格式和约定，输入:crontab -u root -e 进入vi编辑模式，编辑的内容一定要符合下面的格式:*/1 * * * * [...]]]></description>
			<content:encoded><![CDATA[<p>cron是一个linux下的定时执行工具，可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务，但它不自动起来，可以用以下的方法启动、关闭这个服务:<span id="more-2444"></span></p>
<p>/sbin/service crond start //启动服务</p>
<p>/sbin/service crond stop //关闭服务</p>
<p>/sbin/service crond restart //重启服务</p>
<p>/sbin/service crond reload //重新载入配置</p>
<p>你也可以将这个服务在系统启动的时候自动启动:</p>
<p>在/etc/rc.d/rc.local这个脚本的末尾加上:</p>
<p>/sbin/service crond start</p>
<p>现在Cron这个服务已经在进程里面了，我们就可以用这个服务了，Cron服务提供以下几种接口供大家使用:</p>
<p>1.直接用crontab命令编辑</p>
<p>cron服务提供crontab命令来设定cron服务的，以下是这个命令的一些参数与说明:</p>
<p>crontab -u //设定某个用户的cron服务，一般root用户在执行这个命令的时候需要此参数</p>
<p>crontab -l //列出某个用户cron服务的详细内容</p>
<p>crontab -r //删除没个用户的cron服务</p>
<p>crontab -e //编辑某个用户的cron服务</p>
<p>比如说root查看自己的cron设置:crontab -u root -l</p>
<p>再例如，root想删除fred的cron设置:crontab -u fred -r</p>
<p>在编辑cron服务时，编辑的内容有一些格式和约定，输入:crontab -u root -e</p>
<p>进入vi编辑模式，编辑的内容一定要符合下面的格式:*/1 * * * * ls &gt;&gt; /tmp/ls.txt</p>
<p>任务调度的crond常驻命令</p>
<p>crond 是linux用来定期执行程序的命令。当安装完成操作系统之后，默认便会启动此任务调度命令。crond命令每分锺会定期检查是否有要执行的工作，如果有要执行的工作便会自动执行该工作。</p>
<p>1、linux任务调度的工作主要分为以下两类：</p>
<p>*系统执行的工作：系统周期性所要执行的工作，如备份系统数据、清理缓存</p>
<p>*个人执行的工作：某个用户定期要做的工作，例如每隔10分钟检查邮件服务器是否有新信，这些工作可由每个用户自行设置。</p>
<p>2.crontab命令选项:</p>
<p>-u指定一个用户,</p>
<p>-l列出某个用户的任务计划,</p>
<p>-r删除某个用户的任务,</p>
<p>-e编辑某个用户的任务</p>
<p>3.cron文件语法:</p>
<p>分 小时 日 月 星期 命令</p>
<p>0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)</p>
<p>4.记住几个特殊符号的含义:</p>
<p>&#8220;*&#8221;代表取值范围内的数字,</p>
<p>&#8220;/&#8221;代表&#8221;每&#8221;,</p>
<p>&#8220;-&#8221;代表从某个数字到某个数字,</p>
<p>&#8220;,&#8221;分开几个离散的数字</p>
<p>一、任务调度设置文件的写法</p>
<p>可用crontab -e命令来编辑,编辑的是/var/spool/cron下对应用户的cron文件,也可以直接修改/etc/crontab文件</p>
<p>具体格式如下：</p>
<p>Minute Hour Day Month Dayofweek command</p>
<p>分钟 小时 天 月 天每星期 命令</p>
<p>每个字段代表的含义如下：</p>
<p>Minute 每个小时的第几分钟执行该任务</p>
<p>Hour 每天的第几个小时执行该任务</p>
<p>Day 每月的第几天执行该任务</p>
<p>Month 每年的第几个月执行该任务</p>
<p>DayOfWeek 每周的第几天执行该任务</p>
<p>Command 指定要执行的程序</p>
<p>在这些字段里，除了“Command”是每次都必须指定的字段以外，其它字段皆为可选字段，可视需要决定。对于不指定的字段，要用“*”来填补其位置。</p>
<p>举例如下：</p>
<p>5 * * * * ls 指定每小时的第5分钟执行一次ls命令</p>
<p>30 5 * * * ls 指定每天的 5:30 执行ls命令</p>
<p>30 7 8 * * ls 指定每月8号的7：30分执行ls命令</p>
<p>30 5 8 6 * ls 指定每年的6月8日5：30执行ls命令</p>
<p>30 6 * * 0 ls 指定每星期日的6:30执行ls命令[注：0表示星期天，1表示星期1，以此类推，也可以用英文来表示，sun表示星期天，mon表示星期一等。]</p>
<p>30 3 10,20 * * ls 每月10号及20号的3：30执行ls命令[注：“，”用来连接多个不连续的时段]</p>
<p>25 8-11 * * * ls 每天8-11点的第25分钟执行ls命令[注：“-”用来连接连续的时段]</p>
<p>*/15 * * * * ls 每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]</p>
<p>30 6 */10 * * ls 每个月中，每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6：30执行一次ls命令。 ]</p>
<p>每天7：50以root 身份执行/etc/cron.daily目录中的所有可执行文件</p>
<p>50 7 * * * root run-parts /etc/cron.daily [ 注：run-parts参数表示，执行后面目录中的所有可执行文件。 ]</p>
<p>二、新增调度任务</p>
<p>新增调度任务可用两种方法：</p>
<p>1、在命令行输入: crontab -e 然后添加相应的任务，wq存盘退出。</p>
<p>2、直接编辑/etc/crontab 文件，即vi /etc/crontab，添加相应的任务。</p>
<p>三、查看调度任务</p>
<p>crontab -l //列出当前的所有调度任务</p>
<p>crontab -l -u jp //列出用户jp的所有调度任务</p>
<p>四、删除任务调度工作</p>
<p>crontab -r //删除所有任务调度工作</p>
<p>五、任务调度执行结果的转向</p>
<p>例1：每天5：30执行ls命令，并把结果输出到/jp/test文件中</p>
<p>30 5 * * * ls &gt;/jp/test 2&gt;&amp;1</p>
<p>注：2&gt;&amp;1 表示执行结果及错误信息。</p>
<p>编辑/etc/crontab 文件配置cron</p>
<p>cron服务每分钟不仅要读一次/var/spool/cron内的所有文件，还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服务做一些事情。用crontab配置是针对某个用户的，而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:</p>
<p>SHELL=/bin/bash</p>
<p>PATH=/sbin:/bin:/usr/sbin:/usr/bin</p>
<p>MAILTO=root //如果出现错误，或者有数据输出，数据作为邮件发给这个帐号</p>
<p>HOME=/ //使用者运行的路径,这里是根目录</p>
<p># run-parts</p>
<p>01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本</p>
<p>02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本</p>
<p>22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本</p>
<p>42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本</p>
<p>大家注意&#8221;run-parts&#8221;这个参数了，如果去掉这个参数的话，后面就可以写要运行的某个脚本名，而不是文件夹名了</p>
<p>例如： 1、在命令行输入: crontab -e 然后添加相应的任务，wq存盘退出。</p>
<p>2、直接编辑/etc/crontab 文件，即vi /etc/crontab，添加相应的任务</p>
<p>11 2 21 10 * rm -rf /mnt/fb</p>
<p>来源:<a href="http://www.5vo.cn/html/simplified-chinese-linux-cron-program-tasks-explained-in-detail.html" target="_blank">无忧博客</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2444/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux如何加入域</title>
		<link>http://www.1uu2.com/archives/2387</link>
		<comments>http://www.1uu2.com/archives/2387#comments</comments>
		<pubDate>Fri, 19 Aug 2011 16:13:39 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2387</guid>
		<description><![CDATA[说明:本文为LINUX加入WINDOWS域的具体情况作一些说明,关于如何加入到域,本文不再详述,仅提供一个配置样板,如果有不了解的,可以再查看相关文章. *-====================-* * Linux To Windows AD *-====================-* - 基本概念 * PDC &#8211; 主域控制器 * BDC &#8211; 备份域控制器 * KDC &#8211; 密钥颁发中心,Kerberos服务器 * PAM &#8211; 可插拨认证模块 * SRV &#8211; DNS服务资源记录 - 域模式 * PRC &#8211; LINUX以Windows2000/NT4样式加入到域中 * ADS &#8211; 活动目录,Windows2003,WindowsXP * 混合 &#8211; 有最好的兼容性 - 软件包Sw * Samba: yum install samba.* samba-common.* samba-winbind-client.* * Winbind: [...]]]></description>
			<content:encoded><![CDATA[<p>说明:本文为LINUX加入WINDOWS域的具体情况作一些说明,关于如何加入到域,本文不再详述,仅提供一个配置样板,如果有不了解的,可以再查看相关文章.<span id="more-2387"></span></p>
<p>*-====================-*</p>
<p>* Linux To Windows AD</p>
<p>*-====================-*</p>
<p>- 基本概念</p>
<p>* PDC &#8211; 主域控制器</p>
<p>* BDC &#8211; 备份域控制器</p>
<p>* KDC &#8211; 密钥颁发中心,Kerberos服务器</p>
<p>* PAM &#8211; 可插拨认证模块</p>
<p>* SRV &#8211; DNS服务资源记录</p>
<p>- 域模式</p>
<p>* PRC &#8211; LINUX以Windows2000/NT4样式加入到域中</p>
<p>* ADS &#8211; 活动目录,Windows2003,WindowsXP</p>
<p>* 混合 &#8211; 有最好的兼容性</p>
<p>- 软件包Sw</p>
<p>* Samba: yum install samba.* samba-common.* samba-winbind-client.*</p>
<p>* Winbind: yum install samba-winbind.*</p>
<p>* Samba4: yum install samba4.* ;A newer version of samba</p>
<p>* Kerberos5: yum install pam_krb5.* krb5-workstation.* krb5-libs.*</p>
<p>* ldconfig</p>
<p>* ldconfig -v | grep winbind</p>
<p>* ls /usr/lib/libnss_winbind.so</p>
<p>- 配置文件</p>
<p>- NSS: /etc/nsswitch.conf</p>
<p>; 指示系统如何查找系统配置文件</p>
<p>; ACTION=Modify</p>
<p>* password: files winbind</p>
<p>* group: files winbind</p>
<p>- Samba: /etc/smb.conf</p>
<p>; 与共享文件夹相关的配置</p>
<p>; DomainMode = ActiveDirectory</p>
<p>*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*</p>
<p>[global]</p>
<p>client use spnego = no</p>
<p>server signing = auto</p>
<p>workgroup = CAMPUS</p>
<p># The SHORT-DOMAIN name of your domain, you need to modify</p>
<p>wins support = yes</p>
<p>wins server = 10.0.0.4</p>
<p># Controller of the domain, You need to modify it to your own</p>
<p>wins proxy = yes</p>
<p>security = ADS</p>
<p># or AD,ADS,domain, DOMAIN is the RPC mode</p>
<p>acl compatibility = win2k</p>
<p>idmap uid = 16777216-33554431</p>
<p># Set based on your user count</p>
<p>idmap gid = 16777216-33554431</p>
<p>password server = 10.0.0.4</p>
<p># Domain Controller</p>
<p>map to guest = bad user</p>
<p>guest ok = no</p>
<p>realm = CAMPUS.COM</p>
<p># You need to keep the same with file krb5.conf defined</p>
<p># encrypt psswords = yes</p>
<p># Encrypt PASS, not supported by some version of samba</p>
<p>winbind use default domain = yes</p>
<p># winbind separator = %</p>
<p>template homedir = /home/%D/%U</p>
<p># A mode 777 should be set on /home/%D</p>
<p>template shell = /bin/bash</p>
<p>[homes]</p>
<p>comment = %S</p>
<p>path =/home/%D/%S</p>
<p>writeable = yes</p>
<p>browsable = yes</p>
<p>; valid users = %S</p>
<p>valid users = CAMPUS/%S</p>
<p>*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*</p>
<p>* Kerberos: /etc/krb5.conf</p>
<p>*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*</p>
<p>[logging]</p>
<p>default = FILE:/var/log/krb5libs.log</p>
<p>kdc = FILE:/var/log/krb5kdc.log</p>
<p>admin_server = FILE:/var/log/kadmind.log</p>
<p>[libdefaults]</p>
<p>default_realm = CAMPUS.COM</p>
<p>dns_lookup_realm = false</p>
<p>dns_lookup_kdc = false</p>
<p>[realms]</p>
<p>CAMPUS.COM = {</p>
<p>kdc = ADS.CAMPUS.COM:88</p>
<p>admin_server = ADS.CAMPUS.COM:749</p>
<p>default_domain = campus.com</p>
<p>}</p>
<p># This is a REALMS to DOMAIN MAPPING, REALMS Format is uppercase</p>
<p>[domain_realm]</p>
<p>.campus.com = CAMPUS.COM</p>
<p>campus.com = CAMPUS.COM</p>
<p># Build the mapping</p>
<p>[kdc]</p>
<p>profile = /var/kerberos/krb5kdc/kdc.conf</p>
<p>[appdefaults]</p>
<p>pam = {</p>
<p>debug = false</p>
<p>ticket_lifetime = 36000</p>
<p>renew_lifetime = 36000</p>
<p>forwardable = true</p>
<p>krb4_convert = false</p>
<p>}</p>
<p>*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*</p>
<p>* 重启samba: service smb restart</p>
<p>* 重启Winbind: service winbind restart</p>
<p>* 初始化KDC: net ads kerberos kinit</p>
<p>* 加域: net rpc join -S ADS.CAMPUS.COM -U Administrator%</p>
<p>* 查看信息: net rpc info; net ads testjoin; net ads</p>
<p>* 退域: net ads leave -S ADS.CAMPUS.COM -U Administrator%</p>
<p>* 查看用户信息: wbinfo -u, wbinfo -t</p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2387/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何查看Linux系统安装的时间</title>
		<link>http://www.1uu2.com/archives/2382</link>
		<comments>http://www.1uu2.com/archives/2382#comments</comments>
		<pubDate>Wed, 17 Aug 2011 07:47:12 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2382</guid>
		<description><![CDATA[我们 SUN 实验室每台服务器上架后都需要填写一个表格，这个表格包括详细的机器硬件配置、操作系统版本和安装时间、网络配置、机器名、MAC 地址和 IP、安装的软件和用途、安全级别和策略、联系人、上架时间、机柜号等。昨天有位管理员忘了填写操作系统的安装时间，跑来问怎么查看 Linux 系统的安装日期和时间(过了2个月谁还记得啊)。 有个办法是查看 lost+found 目录状态，因为这个目录一般很少用到，改动最少(很可能无任何改动)，而其他目录比如 /bin, /home 等因为经常升级系统、创建用户等操作会修改目录状态。VPSee 在自己的一台 VPS 结点服务器上验证了一下，这台服务器是去年3月10日安装的系统，中途升级系统重启一次，然后连续满负荷跑了342天没有重启： &#160; 　　$ stat /lost+found/ File: `/lost+found/&#8217; Size: 16384 Blocks: 32 IO Block: 4096 directory Device: 805h/2053d Inode: 11 Links: 2 Access: (0700/drwx&#8212;&#8212;) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2010-03-11 02:40:20.000000000 -0800 Modify: 2010-03-10 19:14:34.000000000 -0800 Change: [...]]]></description>
			<content:encoded><![CDATA[<p>我们 SUN 实验室每台服务器上架后都需要填写一个表格，这个表格包括详细的机器硬件配置、操作系统版本和安装时间、网络配置、机器名、MAC 地址和 IP、安装的软件和用途、安全级别和策略、联系人、上架时间、机柜号等。昨天有位管理员忘了填写操作系统的安装时间，跑来问怎么查看 Linux 系统的安装日期和时间(过了2个月谁还记得啊)。<span id="more-2382"></span></p>
<p>有个办法是查看 lost+found 目录状态，因为这个目录一般很少用到，改动最少(很可能无任何改动)，而其他目录比如 /bin, /home 等因为经常升级系统、创建用户等操作会修改目录状态。VPSee 在自己的一台 VPS 结点服务器上验证了一下，这台服务器是去年3月10日安装的系统，中途升级系统重启一次，然后连续满负荷跑了342天没有重启：</p>
<p>&nbsp;</p>
<table width="95%" border="0" cellspacing="0" cellpadding="6" align="center">
<tbody>
<tr>
<td bgcolor="#fdfddf">　　$ stat /lost+found/<br />
File: `/lost+found/&#8217;<br />
Size: 16384 Blocks: 32 IO Block: 4096 directory<br />
Device: 805h/2053d Inode: 11 Links: 2<br />
Access: (0700/drwx&#8212;&#8212;) Uid: ( 0/ root) Gid: ( 0/ root)<br />
Access: 2010-03-11 02:40:20.000000000 -0800<br />
Modify: 2010-03-10 19:14:34.000000000 -0800<br />
Change: 2010-03-10 19:14:34.000000000 -0800</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>还有一种办法是查看 bin, daemon, sys, adm 等这些帐号的建立时间，这些帐号是在系统安装的时候创建的，所以这些帐号的创建时间基本上就是 Linux 系统的安装时间：</p>
<p>&nbsp;</p>
<table width="95%" border="0" cellspacing="0" cellpadding="6" align="center">
<tbody>
<tr>
<td bgcolor="#fdfddf">　　# passwd -S bin<br />
bin LK 2010-03-10 0 99999 7 -1 (Alternate authentication scheme in use.)<br />
# passwd -S daemon<br />
daemon LK 2010-03-10 0 99999 7 -1 (Alternate authentication scheme in use.)</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>上面这个看帐号创建时间的方式有局限性，不同的 Linux 发行版安装的时候处理 bin, daemon 这些系统帐号的方式不同，有的是直接从安装光盘拷贝这些帐号和相关文件，有的是安装脚本自动创建。只有安装脚本自动创建的发行版本才能根据帐号的创建时间来判断系统的安装时间。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2382/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>跟踪程序在Linux下的执行的函数调用</title>
		<link>http://www.1uu2.com/archives/2353</link>
		<comments>http://www.1uu2.com/archives/2353#comments</comments>
		<pubDate>Thu, 07 Jul 2011 12:42:00 +0000</pubDate>
		<dc:creator>Linux之友</dc:creator>
				<category><![CDATA[Linux技巧]]></category>
		<category><![CDATA[跟踪程序]]></category>

		<guid isPermaLink="false">http://www.1uu2.com/?p=2353</guid>
		<description><![CDATA[对于一个程序，通常我们可以使用gdb之类的调用工具设定断点进行调用。然而Linux系统提供了众多的跟踪工具，可以让我们在没有源代码的情况下跟踪程序都执行了哪些系统调用、动态库调用、栈情况以及接收信号等。可以让我们不停止程序来观察程序的执行流程。 strace 显示执行程序的系统调用及接收信号情况 strace [strace 选项] 可执行程序 可执行程序参数 选项说明： -o filename 将输出写到文件filename中 -f 跟踪子进程的执行，适合多线程程序 -ff 如果使用了-o指定输出文件，则将每个子进程都写入到filename.pid中 -s strsize，指定最大字串大小，默认为32. -r 打印相对时间戳 -t 打印实际时间 -tt 打印毫秒级 -ttt 打印微秒级时间 -x 将所有非ASCII字符串显示为十六进制字串 -xx 将所有字符串显示为十六进制 -P pid 附着于进程进行跟踪，并在ctrl+c后离开保持被跟踪程序执行。 -e key=[!]value[,value]或-evalue，只显示value的系统调用 key包括trace、abbrev、verbose、raw、signal、read、write，value为系统调用的符号。 例如-e trace=open。默认使用trace=all。 为了方便使用value定义了一些不同类型的系统调用：file代表所有文件相关调用，process涉及相关进程的调用，network涉及相关网络系统调用，signal代表所有信号相关的系统调用，此外还有ipc,desc。其他的key如abbrev、verbose、raw表示使用什么样的输出方式。signal可以跟踪特定信号集的接收情况。默认为signal=ALL，可以使用SIGIO这种方式。而read/write则可以指定跟踪写特定文件描述符的动作，并将读写数据以十六进制的方式打印出来。例如-e read=3,5 ltrace 显示执行程序的库调用及接收信号情况 其与strace的使用参数类似，支持-e -f -P -s -t -tt -tt -o -ff等参数，此外它还支持下面的一些参数 -C &#8211;demangle 转换低级编译器的符号令用户易看，例如C++等的mangle操作。 -l [...]]]></description>
			<content:encoded><![CDATA[<p>对于一个程序，通常我们可以使用gdb之类的调用工具设定断点进行调用。然而Linux系统提供了众多的跟踪工具，可以让我们在没有源代码的情况下跟踪程序都执行了哪些系统调用、动态库调用、栈情况以及接收信号等。可以让我们不停止程序来观察程序的执行流程。<span id="more-2353"></span></p>
<p>strace 显示执行程序的系统调用及接收信号情况</p>
<p>strace [strace 选项] 可执行程序 可执行程序参数</p>
<p>选项说明：</p>
<p>-o filename 将输出写到文件filename中</p>
<p>-f 跟踪子进程的执行，适合多线程程序</p>
<p>-ff 如果使用了-o指定输出文件，则将每个子进程都写入到filename.pid中</p>
<p>-s strsize，指定最大字串大小，默认为32.</p>
<p>-r 打印相对时间戳</p>
<p>-t 打印实际时间 -tt 打印毫秒级 -ttt 打印微秒级时间</p>
<p>-x 将所有非ASCII字符串显示为十六进制字串</p>
<p>-xx 将所有字符串显示为十六进制</p>
<p>-P pid 附着于进程进行跟踪，并在ctrl+c后离开保持被跟踪程序执行。</p>
<p>-e key=[!]value[,value]或-evalue，只显示value的系统调用</p>
<p>key包括trace、abbrev、verbose、raw、signal、read、write，value为系统调用的符号。</p>
<p>例如-e trace=open。默认使用trace=all。</p>
<p>为了方便使用value定义了一些不同类型的系统调用：file代表所有文件相关调用，process涉及相关进程的调用，network涉及相关网络系统调用，signal代表所有信号相关的系统调用，此外还有ipc,desc。其他的key如abbrev、verbose、raw表示使用什么样的输出方式。signal可以跟踪特定信号集的接收情况。默认为signal=ALL，可以使用SIGIO这种方式。而read/write则可以指定跟踪写特定文件描述符的动作，并将读写数据以十六进制的方式打印出来。例如-e read=3,5</p>
<p>ltrace 显示执行程序的库调用及接收信号情况</p>
<p>其与strace的使用参数类似，支持-e -f -P -s -t -tt -tt -o -ff等参数，此外它还支持下面的一些参数</p>
<p>-C &#8211;demangle 转换低级编译器的符号令用户易看，例如C++等的mangle操作。</p>
<p>-l &#8211;library libname,lib&#8230; 只显示对libname中的库调用</p>
<p>-S 显示系统调用，-L 不显示库调用</p>
<p>-n num 当嵌套调用时，进行缩进显示</p>
<p>对于不同的库中的调用，列于/etc/ltrace.conf文件中</p>
<p>pstack 打印命中时程序的调用栈及相应参数</p>
<p>pstack pid即可</p>
]]></content:encoded>
			<wfw:commentRss>http://www.1uu2.com/archives/2353/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

