分类存档: Moo - 第14页

跨网段组播问题

最近工作上遇到一个需要udp组播推送消息的功能,网络配置上采用PIM-SM,稀疏模式。
用了许多网上的组播例程,同网段可以,不同网段都无法发送成功。当时RP上监听端已经建立了(*,G)的表项,
发送端无法建立起(S,G)。最后研究了下VLC的源码,在发送端加了AddSourceMemberShip的动作,
成功建立了组播通路。
按MSDN的说法,发送的时候是不需要有加入组播组的动作的,到底是不是这样,还是他们的PIM-SM配置有误,求解。。。

解决ubuntu 13.04下vmware9无法输入LicenseKey

64位ubuntu 13.04 装了Vmware Workstation 9,点击Enter License Key后无反应,
可以在Terminal输入:
/usr/lib/vmware/bin/vmware-vmx-debug –new-sn xxxxx-xxxxx-xxxxx-xxxxx-xxxxx

高考满分作文–感觉空洞了一些

12-E5A8F7EA-55337-800遗失的童真
       当暮霭沉沉之时,我们被劝说要相信楚天辽阔;当草长莺飞之时,我们被劝说要防备前方蜀道之难;当我们成长到每一个阶段时,我们都被提醒着完成不合时宜的任务。于是,童真就如那风铃,渐行渐远,消逝不见。
      “孩子从卖气球的人手中牵走一个心愿”,多么可爱而美好的诗句,甚至可以想象那洋溢着灿烂的笑脸。而如今这样的笑脸在冰封冻结。本该童真的年纪,却一脸愁苦,为学业奔波。我们不应抱怨现在的孩子为何圆滑世故,我们应反省是什么造成了童真的遗失,又是什么加剧了这种遗失的势头。
       反观社会,我们清醒地看到一个充满竞争意识,强调优胜劣汰的社会。当成年人大多在为金钱名利所奔波时,当与孩子共处时的谈资均为事业发展、利润亏损时,试问一张白纸又怎能不被沾染得墨迹斑斑?与此同时,将大人的不满足强加于孩子幼小的成长历程之中,狼爸、虎妈层出不穷的当下,一个孩子的童真不是被孩子淡忘,而是被一种恶性环境所扼杀。汪增祺描写金岳霖先生时,曾有金先生拿大石榴与孩子们斗鸡,上课上到一半时,捉虱子的场景。这些童真未泯的形象,让我们认识到一个学者、一个智者不应为虚浮名利勾心斗角忙碌终生,而应是对生活充满了热爱和积极的乐观情绪。
      在一个鼓吹神童的媒体时代,在我心里,不是童亵渎了神,而是神亵渎了童。孩子的眼光是直线的,不会转弯,也碌如此,他能看到我们遗失的美好,他的创造、他的发问让我们看到了世界的另一面。童真的目光,或许就像是穿越时空的爱,能够照亮冰点以上的风景。
这份童真,这份初心,倘若一直坚守,如同守护一株鲜红欲滴的玫瑰,梦过于美好,守护也便更加沉重。天上人间,现实让人们知道自由不过是猎人与猎物之间的距离。但为什么现实让人们害怕得连一个梦的开端也不肯轻易地为孩子许下呢?
       遗失的童真被一种潜在的暴力撕扯得支离破碎。最好的成长,不是小小年纪就考上了名牌大学,不是小小年纪就深谙世俗之法,不是小小年纪就挥毫千里、琴声悠扬。我更愿看到“最喜小儿无赖,村头卧剥莲蓬”的无忧闲适之景。未来或许残酷,但心中有好奇、有想象、有创造,便不会畏惧。
       有些事终要经历,那便到时深究,有些事如此美好,为何不好好珍惜?遗失的童真,带给了我们怅惘,但愿这番省悟能让天真无邪的笑声在风中散播得更久一些。(60分)

120一些年之后,我要跟你去山下人迹稀少的小镇生活。清晨爬到高山巅顶,下山去集市买蔬菜水果。烹煮打扫。午后读一本书。晚上在杏花树下喝酒,聊天,直到月色和露水清凉。在梦中,行至岩凤尾蕨茂盛的空空山谷,鸟声清脆,树上种子崩裂…一起在树下疲累而眠。醒来时,我尚年少,你未老。

例行维护

21:00 5/9/2013

10:39 5/14/2013 Done

2013五一末

Geroldsee, Bavaria, Germany
青峰两处,蜿蜒多少里,
夕阳落,一阕晚霞随离歌,
漫漫云天际。

Mac下配置Git-TF来连接TFS2012

christinamanchenko1Git-TF是微软提供的让TFS Server支持Git的工具,但网上几乎没有文章来针对Mac OS下安装Git-TF的说明,Mac下配置Git-TF的操作步骤如下:
下载文件

下载后,解压缩文件到本地,本例中,解压缩到 /Users/[ME]/Git-Tf 目录,其中[ME]是当前登录用户名

添加环境变量

要在MAC中添加环境变量,保证能访问到Git-Tf的目录,参考如下步骤
打开Terminal命令行窗口,并进入用户根目录
cd ~/
验证 .profile 文件是否存在:
ls -la | grep “.profile”
如果文件没有找到,用命令行创建:
touch .profile
打开.profile问津,并编辑
open .profile
在文件底部添加如下代码,其中”/Users/[ME]/Git-Tf/”请修改为你的Git-Tf目录
export PATH=”/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/”:$PATH
export PATH=”/Users/[ME]/Git-Tf/”:$PATH
保存,并关闭文本编辑窗口,回到命令行窗口,输入如下命令行:
source .profile

获取项目

重新启动命令行窗口,输入如下命令测试,其中的 shanghai\liujunmin 请替换自己的TFS登录账号:
git tf clone http://pd-tfs2012:8080/tfs $/demo
Username:shanghai\liujunmin
Password:***********

如果要保存账号密码,可以用如下命令,其中的shanghai\liujunmin请替换自己的TFS登录账号:
git config git-tf.server.username “shanghai\liujunmin”
git config git-tf.server.password ***********

配置完成

试用后,发现Git-tf可以在XCode中进行Commit,但不能直接在XCode中Push,只能在命令行中调用Checkin命令去提交。

4-1

我就是我 是颜色不一样的烟火6a600c338744ebf89731ec40d8f9d72a6059a709

OSX/iOS 多线程方法

1.使用NSThread
NSThread提供了创建线程的途径,还可以提供了检测当前线程是否是主线程的方法。 使用NSThread创建一个新的线程有两种方式:
1.创建一个NSThread的对象,调用其start方法。对于这种方式的NSThread对象的创建,可以使用一个目标对象的方法初始化一个NSThread对象,或者创建一个继承NSThread类的子类,实现其main方法,然后在直接创建这个子类的对象。
2.使用 detachNewThreadSelector:toTarget:withObject:这个类方法创建一个线程,这个比较直接了,直接使用目标对象的方法作为线程启动入口。
2.使用NSObject
其实NSObject直接就加入了多线程的支持,允许对象的某个方法在后台运行。如:
[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];
3.POSIX Thread
由于Mac和iOS都是基于Darwin系统,Darwin系统的XUN内核,是基于Mach和BSD的,继承了BSD的POSIX接口,所以可以直接使用POSIX线程的相关接口来使用线程。
创建线程的接口为 pthread_create,当然在创建之前可以通过相关函数设置好线程的属性。以下为POSIX线程使用简单的例子。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void *pthreadRoutine(void *);

int main (int argc, const char * argv[])
{
    pthread_attr_t  attr;
    pthread_t       pthreadID;
    int             returnVal;
    
    returnVal = pthread_attr_init(&attr);
    returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    int threadError = pthread_create(&pthreadID, &attr, &pthreadRoutine, NULL);
    returnVal = pthread_attr_destroy(&attr);
    
    if (threadError != 0)
    {
        // Report an error.
    }
    
    sleep(10);
    
    return 0;
}

void *pthreadRoutine(void *data){
    int count = 0;
    while (1) {
        printf("count = %d\n",count++);
        sleep(1);
    }
    return NULL;
}

多线程进阶
NSOperation&NSOperationQueue
很多时候我们使用多线程,需要控制线程的并发数,毕竟线程也是消耗系统资源的,当程序中同时运行的线程过多时,系统必然变慢。 所以很多时候我们会控制同时运行线程的数目。
NSOperation可以封装我们的操作,然后将创建好的NSOperation对象放到NSOperationQueue中,OperationQueue便开始启动新的线程去执行队列中的操作,OperationQueue的并发度是可以通过如下方式进行设置:
– (void)setMaxConcurrentOperationCount:(NSInteger)count
GCD
GCD是Grand Central Dispatch的缩写,是一系列的BSD层面的接口,在Mac 10.6 和iOS4.0以后才引入的,且现在NSOperation和NSOperationQueue的多线程的实现就是基于GCD的。目前这个特性也被移植到FreeBSD上了,可以查看libdispatch这个开源项目。
比如一个在UIImageView中显示一个比较大的图片

dispatch_queue_t imageDownloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    
dispatch_async(imageDownloadQueue, ^{
        NSURL *imageURL = [NSURL URLWithString:@"http://test.com/test.png"];
       NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        UIImage *image = [UIImage imageWithData:imageData];
       dispatch_async(dispatch_get_main_queue(), ^{
            [imageView setImage:image];//UIKit必须在主线程执行
        });
    });

当然,GCD除了处理多线程外还有很多非常好的功能,其建立在强大的kqueue之上,效率也能够得到保障。
四.线程间通信
线程间通信和进程间通信从本质上讲是相似的。线程间通信就是在进程内的两个执行流之间进行数据的传递,就像两条并行的河流之间挖出了一道单向流动长沟,使得一条河流中的水可以流入另一条河流,物质得到了传递。
1.performSelect On The Thread
框架为我们提供了强制在某个线程中执行方法的途径,如果两个非主线程的线程需要相互间通信,可以先将自己的当前线程对象注册到某个全局的对象中去,这样相互之间就可以获取对方的线程对象,然后就可以使用下面的方法进行线程间的通信了,由于主线程比较特殊,所以框架直接提供了在出线程执行的方法。

@interface NSObject (NSThreadPerformAdditions)

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
// equivalent to the first method with kCFRunLoopCommonModes

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
// equivalent to the first method with kCFRunLoopCommonModes
    ...
@end

2.Mach Port
在苹果的Thread Programming Guide的Run Pool一节的Configuring a Port-Based Input Source 这一段中就有使用Mach Port进行线程间通信的例子。 其实质就是父线程创建一个NSMachPort对象,在创建子线程的时候以参数的方式将其传递给子线程,这样子线程中就可以向这个传过来的NSMachPort对象发送消息,如果想让父线程也可以向子线程发消息的话,那么子线程可以先向父线程发个特殊的消息,传过来的是自己创建的另一个NSMachPort对象,这样父线程便持有了子线程创建的port对象了,可以向这个子线程的port对象发送消息了。
当然各自的port对象需要设置delegate以及schdule到自己所在线程的RunLoop中,这样来了消息之后,处理port消息的delegate方法会被调用,你就可以自己处理消息了。
五.RunLoop
RunLoop从字面上看是运行循环的意思,这一点也不错,它确实就是一个循环的概念,或者准确的说是线程中的循环。 本文一开始就提到有些程序是一个圈,这个圈本质上就是这里的所谓的RunLoop,就是一个循环,只是这个循环里加入很多特性。
首先循环体的开始需要检测是否有需要处理的事件,如果有则去处理,如果没有则进入睡眠以节省CPU时间。 所以重点便是这个需要处理的事件,在RunLoop中,需要处理的事件分两类,一种是输入源,一种是定时器,定时器好理解就是那些需要定时执行的操作,输入源分三类:performSelector源,基于端口(Mach port)的源,以及自定义的源。编程的时候可以添加自己的源。RunLoop还有一个观察者Observer的概念,可以往RunLoop中加入自己的观察者以便监控着RunLoop的运行过程,CFRunLoop.h中定义了所有观察者的类型:

enum CFRunLoopActivity {
   kCFRunLoopEntry = (1 << 0),
   kCFRunLoopBeforeTimers = (1 << 1),
   kCFRunLoopBeforeSources = (1 << 2),
   kCFRunLoopBeforeWaiting = (1 << 5),
   kCFRunLoopAfterWaiting = (1 << 6),
   kCFRunLoopExit = (1 << 7),
   kCFRunLoopAllActivities = 0x0FFFFFFFU
};
typedef enum CFRunLoopActivity CFRunLoopActivity;

如果你使用过select系统调用写过程序你便可以快速的理解runloop事件源的概念,本质上讲事件源的机制和select一样是一种多路复用IO的实现,在一个线程中我们需要做的事情并不单一,如需要处理定时钟事件,需要处理用户的触控事件,需要接受网络远端发过来的数据,将这些需要做的事情统统注册到事件源中,每一次循环的开始便去检查这些事件源是否有需要处理的数据,有的话则去处理。 拿具体的应用举个例子,NSURLConnection网络数据请求,默认是异步的方式,其实现原理就是创建之后将其作为事件源加入到当前的RunLoop,而等待网络响应以及网络数据接受的过程则在一个新创建的独立的线程中完成,当这个线程处理到某个阶段的时候比如得到对方的响应或者接受完了网络数据之后便通知之前的线程去执行其相关的delegate方法。所以在Cocoa中经常看到scheduleInRunLoop:forMode:这样的方法,这个便是将其加入到事件源中,当检测到某个事件发生的时候,相关的delegate方法便被调用。对于CoreFoundation这一层而言,通常的模式是创建输入源,然后将输入源通过CFRunLoopAddSource函数加入到RunLoop中,相关事件发生后,相关的回调函数会被调用。如CFSocket的使用。 另外RunLoop中还有一个运行模式的概念,每一个运行循环必然运行在某个模式下,而模式的存在是为了过滤事件源和观察者的,只有那些和当前RunLoop运行模式一致的事件源和观察者才会被激活。
每一个线程都有其对应的RunLoop,但是默认非主线程的RunLoop是没有运行的,需要为RunLoop添加至少一个事件源,然后去run它。一般情况下我们是没有必要去启用线程的RunLoop的,除非你在一个单独的线程中需要长久的检测某个事件。

转自 http://geeklu.com/2012/02/thread/

Back from Holiday

IMG_0486