分类目录归档:技术文献

Qt::ConnectionType 解析

signal/slot在底层会使用三种方式传递消息。参见QObject::connect()方法:
bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoCompatConnection )
最后一个参数是就是传递消息的方式了,有四个取值:

Qt::DirectConnection
When emitted, the signal is immediately delivered to the slot.
假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这4个slot按连接的时间顺序调用一遍。显然这种方式不能跨线程(传递消息)。

Qt::QueuedConnection
When emitted, the signal is queued until the event loop is able to deliver it to the slot.
假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这个signal包装成一个 QEvent,放到消息队列里。QApplication::exec()或者线程的QThread::exec()会从消息队列里取消息,然后调用 signal关联的几个slot。这种方式既可以在线程内传递消息,也可以跨线程传递消息。

Qt::BlockingQueuedConnection
Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application.
与Qt::QueuedConnection类似,但是会阻塞等到关联的slot都被执行。这里出现了阻塞这个词,说明它是专门用来多线程间传递消息的。

Qt::AutoConnection
If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.
这种连接类型根据signal和slot是否在同一个线程里自动选择Qt::DirectConnection或Qt::QueuedConnection

这样看来,第一种类型的效率肯定比第二种高,毕竟第二种方式需要将消息存储到队列,而且可能会涉及到大对象的复制(考虑sig_produced(BigObject bo),bo需要复制到队列里)。

在QtCreator上 使用版本控制系统Git

在一篇介绍Git的文章中,作者说版本控制系统是为懒人准备的,它让懒人们比那些善于备份文档的勤劳人拥有更干净的文件系统以及更多的可以活着的时间。对此我深表赞同。同时在现在快节奏的社会中,提高团队合作效率更是团队生存的关键。所以,这坚定了我选择版本控制系统的信念。

git是我第一个接触的版本控制系统。有同学说你怎么不用SVN啊,我反驳:GitLinux之父LinusTorvalds一手打造的,对于Linux系统和开源项目的管理当然好啦。其实我在QtCreator上搭建git的时候也是费了一番周折呢,现在终于成功了,高兴得想写一篇文章来总结一下。有不对的地方请尽管提出来,我会改正的。

我目前的开发环境:Ubuntu11.10QtCreator2.41Qt4.8

保证正确地安装了QtCreator了吗?请看这里

现在开始安装相关组件了:首先是gitCtrl+Alt+T打开终端,输入sudoapt-get install git,回车,安装git

为了方便地使用git,还必须安装gitk这个git的图形端。命令:sudoapt-get install gitk

随后是团队开发必须的OpenSSH了。因为要和很多台主机进行通信,所以我们必须确保你们的连接是安全的,这里OpenSSH能满足我们的需求。安装命令是:sudoapt-get installopenssh-client。如果你自己创建一个代码库并且让自己的机器成为服务器,那么你还需要安装OpenSSH服务器版本,命令:sudoapt-get install openssh-server

有安装OpenSSH问题的,可以移步至:这里

安装完git后,我们看到,QtCreator已经检测到了git的存在。在版本控制和工具菜单里面都有git选项。

网上有大量git命令行相关的文章,我也不再赘述了,我就介绍git怎样和QtCreator一起使用。注意:QtCreator按照规范将路径中的所有中文转为\nnnn为一个数字)的形式,在git中这样会导致定位失败(因为git可以识别中文路径)。

创建一个新的项目吧,快捷键Ctrl+n。记得项目的路径中不能有中文,必须是纯英文的形式,在这里我建立一个名为“test”的纯C项目。


点击下一步,出现版本控制的选项,选择git,如下图。我们在创建项目的时候会有一个.user文件,保存了一些用户杂项配置,但是不同用户的喜好不同,因此此文件并没有被git管理,不得不说QtCreator这一点为我们考虑得十分细致。


下一步,接下来就不要我说了吧,完成。创建了一个纯C的项目,其实就是HelloWorld。我们假设这个HelloWorld就是第一个版本,我们要将这个版本作为初始版本,那么我们应该点击“工具➡Git➡Commit……“作为我们的第一次提交,也是第一个版本。


填写作者和Email信息后,就可以写说明了。这里对“说明”输入框作一些说明:首先在我这个QtCreator版本一输入中文就崩溃(自动退出),很恼人的,所以这次我就没有填写中文信息了,但是使用git命令(命令:gitcommit,打开GNUnano编辑器)就可以填写中文。此外注意了吗?第一行是用粗体标志的呢,第二行为空,这是因为很多的信息服务(如接下来介绍的log)会将第一行作为题目,后面的作为正文。命令

填写好了,并且选择了需要提交的文件之后,点击提交,这样git就为我们储存了一个版本的信息了。

想要看看自己提交的版本信息吗?点击“工具➡Git➡Log“,可以显示提交的版本信息。如下图:


点击2552bae,就会显示用英文显示的版本信息,英文不好的同学们就糟糕了……


接下来我就要对这个项目做一些修改了,我们让它再显示一个文字:Hellogit!,并且命名这个版本为1.1。首先我们对源文件main.c进行修改,修改后的main.c如下所示:

#include<stdio.h>

intmain(void)

{

printf("Hellogit!\n");

printf("HelloWorld!\n");

return0;

}

其中蓝色字体部分是我们添加的。接下来我们保存一下,但这并不意味着提交到git中了,因为当你点击“工具➡Git➡状态“时,下面的输出会显示这一串文字:

#Changes not staged for commit:

#(use "git add <file>..." to update what will becommitted)

#(use "git checkout -- <file>..." to discard changesin working directory)

#

#modified: main.c

#

#Untracked files:

#(use "git add <file>..." to include in what will becommitted)

#

#test.pro.user

nochanges added to commit (use "git add" and/or "gitcommit -a")

显示了我们的main.c已经修改,但未提交至gittest.pro.user未受git管理,因为上文说过了,每一个用户杂项都由一个.user保存着,失去它不会对项目的设置构成影响)。于是我们还得再提交(commit)一下了。


填完了后点击提交,新的版本1.1就完成了。怎么样,是不是很简单啊。

查看一下log(工具➡Git➡Log),现在有两个版本了!


假设我们的1.1版本写得不好,或者把原有的代码改混乱了,我们想还原到原来的版本1.0那该怎么办呢?很简单,使用gitk就可以解决问题。打开gitk,出现这样的界面:


选择Ver1.0,点击右键,选择“Resetnaster branch tohere”,在弹出的对话框中选择Hard,并且单击OK就完成了版本的还原。需要注意的是,选择Hard模式意味着在新版本上的一切修改都作废,所以要慎重处理。

回到QtCreator界面,发现提示重新载入文件,点击“全部是”就可以了。

提到版本控制,就不得不提到它的一个重要的功能:分支功能。假如我们制作项目需要一些差异化的版本(例如Windows7家庭版和Windows7旗舰版等),但是它们都是拥有相同的部分,仅仅有一些部分是不同的,那么我们完全可以先制作相同的底层部分,然后创建多个分支,分别制作,这样可以拥有两个版本进行评估,最终选择一个更好的版本,也可以两个版本分别发售。在这一点上,git又帮了我们大忙,下面我就介绍在QtCreator上是怎样使用git的分支功能的。有不对的地方请尽管提出来,我会改正的。

我目前的开发环境:Ubuntu11.10QtCreator2.41Qt4.8

首先打开QtCreator,点击“工具➡Git➡Log”来查看我们的Log。如下图:


我们看到第一行中间的括号(HEAD,master),它表示了当前head指针指向的是这个版本,并且这个版本所在的分支是master。怎样查看分支呢?很简单,点击“工具➡Git➡Branches...”就行了。


这里有一个master分支,正是我们以前编辑的分支。接下来我们创建另外一个分支,点击“添加”,创建一个名为Experimental的分支吧(不要选“跟踪本地分支master”)。然后我们先点击Experimental分支,然后点击checkout来切换到Experimental分支。关闭对话框,接下来的动作就在Experimental分支上进行了。

我们在main.c上进行一点修改,去掉HelloWorld显示,改为显示三角形的面积。

其中蓝色的部分是我们更改过的代码,编译运行后我们可以提交这段代码。我们就将这段代码的版本定义为1.2a,提交界面如下图所示:


提交完了后查看版本信息:

此时HEAD指针指向了Experimental分支里面的Ver.1.2a版本了。

这个版本也算是成功的了,于是我将精力转向了另一个版本,我想让它实现对圆锥体积的计算。首先我们要将HEAD指针回调。点击“工具➡Git➡Branches...”,点击master分支进行checkout,切换到master分支,我们看到我们的main.c回到了原来的状态。查看一下Log看是否正确地切换?接下来我们再对main.c进行修改,让它能够计算圆锥的体积:

提交一下,这次将其的版本命名为Ver.1.2b,这样我们项目的两个版本都做好了。如果我们想查看Experimental分支下的当前版本Ver.1.2a的情况,仍然可以使用“工具➡Git➡Branches...”并对Experimental进行checkout就可以了。

嗯,我想知道这两个版本究竟有什么不一样,要来回切换分支并且花很长的时间来找不同吗?哪有这么麻烦,很简单,使用“工具➡Git➡Branches...”,选择一个分支,这里是Experimental,点击diff,来看看和已经checkout了的master分支究竟有什么不同。下面是截图:

这样看不就一清二楚了嘛。

此外还可以将某个分支删除(在“工具➡Git➡Branches...”中),为某个分支进行重命名,以及更加强大的gitk工具,这里就不再向大家介绍了。只要大家入门了,这篇教程就达到目的了。还希望大家一起努力,利用强大的编程工具制作出更加强大的作品来。

C盘空间不足?手动清理Win8.1更新冗余

  微软的每一次Windows系统升级更新都会在系统安装盘上生成一个备份更新,每次给系统打补丁后都会往系统盘里塞文件,关键是这些旧的更新文件不会随着新文件到来而自行毁灭,日积夜累便形成了所谓的WinSxS更新冗余。微软官方也认识到这一问题,因此发布了DISM命令来让用户手动清理释放冗余。本文将分享下如何通过DISM命令来释放清理Win8/Win8.1系统盘中的冗余更新,仅仅保留最新版本。

  Windows冗余在哪里?

  我们说的Windows冗余更新是指位于C盘中的一些补丁更新文件,详细路径为X:\Windows\WinSxS(X:代表用户实际系统盘符)。比如Windows 8.1系统自带的Flash Player会每月更新一次,更新文件存放在amd64_adobe-flash-for-windows或者ia86_adobe-flash-for-windows的备份文件中。

c盘空间不足?手动清理Win8.1冗余更新
图 C盘中拥有大量的Windows更新冗余

  Windows冗余如何清理?

  我们以Win8.1系统为例(同样适用于Win8系统),方法如下:

  1.在传统桌面的开始按钮中右击,选择“命令提示符(管理员)”选项;

c盘空间不足?手动清理Win8.1冗余更新
图 启动命令提示符(管理员)功能

c盘空间不足?手动清理Win8.1冗余更新
图 命令提示符窗口

  2.在弹出的窗口中输入以下代码。(注意空格)

  dism /online /Cleanup-Image /StartComponentCleanup /ResetBase

c盘空间不足?手动清理Win8.1冗余更新
图 输入dism代码

  3.确认后回车,等待系统自动清理;

c盘空间不足?手动清理Win8.1冗余更新
图 Windows冗余清理中

  4.清理完成。

c盘空间不足?手动清理Win8.1冗余更新
图 清理完成

  清理的效果因人而异,如果系统已经长时间使用的话,清理后释放的空间非常可观。当然新系统由于没有太大冗余积累,效果不太明显。

c盘空间不足?手动清理Win8.1冗余更新
图 清理前后系统盘空间对比

Ubuntu VMware虚拟机磁盘压缩

Linux虚拟机里打开终端(Term)输入
sudo /usr/bin/vmware-toolbox-cmd disk list 查看磁盘挂载点,然后执行
sudo /usr/bin/vmware-toolbox-cmd disk shrink / (磁盘挂载点),不清楚的用户可以直接执行
sudo /usr/bin/vmware-toolbox-cmd disk shrinkonly 压缩所有的磁盘,然后会弹出一个
“正在压缩磁盘 D:\Virtual Machines\Ubuntu\Ubuntu.vmdk的对话框,压缩需要很长时间。

在命令行中输入vmware-toolbox启动该功能
首先应确保客户机已经安装VMware Tools工具软件,安装:$ sudo apt-get install open-vm-toolbox

在图形模式下:$ sudo vmware-toolbox (以管理员身份运行才能使用shrink功能)

在命令模式下:$ sudo vmware-toolbox-cmd disk shrink /

如果虚拟机有多个硬盘,sudo vmware-toolbox-cmd disk shrink 后面的参数作为选择硬盘的。具体可参见 $ vmware-toolbox-cmd help disk

问题:安装了open-vm-toolbox后,出现了vmware的文件共享功能不能用,其他功能没检查。

原因:网上查阅相关资料,知道是因为原本安装的vmware tools与open-vm-toolbox冲突了。

解决:使用完open-vm-toolbox后,将其卸载,apt-get remove open-vm-toolbox。并重安装vmware-tools。

为什么Linux不需要碎片整理?

如果你是一个Linux用户,你可能会听说Linux的文件系统不需要碎片整理。你也可能会注意到Linux的发行版本也都没有磁盘碎片整理的功能。这是为什么呢?

为什么Linux不需要碎片整理?
Linux系统中没有“磁盘碎片整理”功能

要理解为什么Linux的文件系统不会想Windows的文件系统一样产生碎片,你首先要明白碎片到底是如何产生的,还有这两大操作系统的文件系统的工作方式到底有什么不同。

什么是磁盘碎片?

很多Windows的用户,甚至包括一些没有经验的用户,都相信定时整理文件系统中的碎片会让他们的电脑运行得更快。但他们都不知道这是为什么。

简单来说,一个硬盘驱动器里面包含了很多扇区,每一个扇区都可以存储一小块数据。对于文件,尤其是比较大的文件来说,他们必须要存储在很多不同的扇区内。假设你的文件系统中有很多不同的文件,每一个文件都被存储在连续的扇区群中。然后,你对增加了其中某一个文件的大小。文件系统首先会尝试对该文件新增加的部分存储在紧挨着原来的扇区群的某个扇区中。但是如果当中没有足够的连续扇区,这个文件就必须要被分解成多个小块,这些操作对于你来说都是可见的。当你的硬盘读取这些文件的时候,他的磁头必须在不同的物理位置间跳转以读取连续的扇区群,这会降低它的速度。

碎片整理就是一个通过逐位(位是文件在磁盘中存储的最小单位)移动文件来减少碎片的精密的过程,以此来确保每一个文件在硬盘中都是连续存储的。

为什么Linux不需要碎片整理?

当然,对于固态硬盘来说这又有点不一样,固态硬盘不需要移动文件也不需要碎片整理。因为对一个SSD(固态硬盘)做碎片整理会减少它的寿命。而且,在最新版本的Windows系统中,你也不再需要为碎片整理担心,因为Windows会自动帮你完成。

Windows的文件系统如何工作

从前微软使用的FAT文件系统——最后一次作为默认系统被看到是在Windows 98和ME,尽管这个系统还在USB驱动器中使用——并不能够很好地排列文件。当你在FAT文件系统中保存文件时,它会尽可能地将文件排列在磁盘的首部。当你存放下一个文件时,它会将这个文件直接存放在第一个文件的后面,以此类推。所以当文件变大,永远都会有碎片产生,因为文件的旁边已经没有空间来存放增加的部分。

微软较新的NTFS文件系统就尝试变得更聪明一点,这个文件系统会在文件周围放置更多名为”缓冲区“的自由空间。但是,任何一个Windows用户都会告诉你,NTFS文件系统总有一天也会产生碎片的。

因为文件系统这样的表现,他们需要碎片整理来保持性能。微软只能在最新版的Windows系统中通过在后台自动运行碎片整理程序来减轻这个问题。

为什么Linux不需要碎片整理?

Linux的文件系统如何工作

Linux的ext2,ext3,ext4文件系统——ext4是Ubuntu和目前大多发行版所采用的文件系统——会以一种更加智能的方式来放置文件。Linux的文件系统会将文件分散在整个磁盘,在文件之间留有大量的自由空间,而不是像Windows那样将文件一个接一个的放置。当一个文件被编辑了并且变大了,一般都会有足够的自由空间来保存文件。如果碎片真的产生了,文件系统就会尝试在日常使用中将文件移动来减少碎片,所以不需要专门的碎片整理程序。

为什么Linux不需要碎片整理?

因为这样的工作方式,你可能会在你的文件系统塞满之后看到碎片。如果文件系统95%(甚至80%)的空间被占用了,你就会开始看到一些碎片。然而,这样的文件系统本来就是设计来在普通使用中减少碎片的。

如果你真的在Linux上出现了碎片的烦恼,你可能就需要一个更大的硬盘了。如果你真的需要对一个文件系统做碎片整理,最简单的可能也是最可靠的方法就是将所有文件拷贝出来,然后清空原来的分区,再将文件拷贝回去。文件系统就会在你拷贝回去的过程中智能地将文件放置好。

你可以使用fsck命令来检测一下一个Linux文件系统的碎片化程度,只需要在输出中查看非连续i节点个数(non-contiguous inodes)就可以了。