MAC COCOA一个简单的多线程程序[2]
2014-06-23 20:27
369 查看
MAC COCOA一个简单的多线程程序[2]
使用RUNLOOP计数,实现一个时间计数器和事件at the same time 运行。STEP 1
H
CODE:
// // EDUAppDelegate.h // test_runloop_multithread // // Created by DMD on 23/6/14. // Copyright (c) 2014 EDU. All rights reserved. // #import <Cocoa/Cocoa.h> @interface EDUAppDelegate : NSObject <NSApplicationDelegate> @property (assign) IBOutlet NSWindow *window; @property (assign) IBOutlet NSTextField *m_Label_TotalCount; @property (assign) IBOutlet NSTextField *m_Label_EveryStartCount; @property (assign) IBOutlet NSTextField *m_Edit_SetCurrentNumber; @property (assign) IBOutlet NSTextField *m_Label_EveryStartCount_Set; @property (assign) IBOutlet NSTextField *m_Label_Restart; @property CFRunLoopSourceRef m_source1; @property CFRunLoopSourceContext m_source1_context; @property CFRunLoopTimerRef m_timer1; @property CFRunLoopTimerContext m_timer1_context; @property NSString *m_total_str; @property int m_total_count; -(void)Show_Msg; -(void) set_label_value:(int)value; @end
M
CODE:
// // EDUAppDelegate.m // test_runloop_multithread // // Created by DMD on 23/6/14. // Copyright (c) 2014 EDU. All rights reserved. // /**************************************** Function : 1个线程来计数,另一个线程来接受用户输入的字符串,互相之间不干扰 目的:测试多线程程序工作,了解原理 *****************************************/ #import "EDUAppDelegate.h" //Define Public Variable +++++ static int g_total_count=0; static EDUAppDelegate *m_window_main; //--------------------------- @implementation EDUAppDelegate //define var +++ @synthesize m_Edit_SetCurrentNumber; @synthesize m_Label_EveryStartCount; @synthesize m_Label_EveryStartCount_Set; @synthesize m_Label_TotalCount; @synthesize m_Label_Restart; @synthesize m_source1; @synthesize m_source1_context; @synthesize m_timer1; @synthesize m_timer1_context; @synthesize m_total_count; @synthesize m_total_str; //--------------- - (void)dealloc { [super dealloc]; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application m_window_main = self; m_total_count=0; m_total_str=@""; } -(void) set_label_value:(int)value { NSString *myname; myname = [NSString stringWithFormat:@"Every Start Count:%d",value]; m_total_str = [m_total_str stringByAppendingString:myname]; m_total_str = [m_total_str stringByAppendingString:@"\n"]; m_Label_EveryStartCount.stringValue = m_total_str; if((m_total_count>0 )&&(m_total_count % 5 ==0)) { m_total_str=@""; m_Label_Restart.stringValue = @"Re-Start 0"; m_total_count =0; [self Show_Msg]; } } //+++++[一个多线程里面调用的函数,C++方式的函数,而不是Object-C方式] // Call Function (2 Method)++ // Do thing 1 void my_do1(void *info __unused) { m_window_main.m_total_count++; printf("Every Start Count: [%d] \n",m_window_main.m_total_count ); [m_window_main set_label_value:m_window_main.m_total_count]; g_total_count++; printf("Total Count is :\"%d\" \n",g_total_count ); m_window_main.m_Label_TotalCount.stringValue =[NSString stringWithFormat:@"Number is [%d]",g_total_count]; } // Timer Function 1 void timer_function1(CFRunLoopTimerRef timer __unused, void *info) { CFRunLoopSourceSignal(info); } // Call Function (2 Method)-- // START - (IBAction)OnBT_Start:(id)sender { // 每一次Start时,一些变量需要Clear // 句柄:m_window_main 是本类的指针,必须初始化,一般为[ClassName1 alloc]init // 这里使用的是本身类,就直接 =self就可以了。 m_window_main.m_total_count =0; m_Label_Restart.stringValue = @"Start!"; m_total_str=@""; // 第一个线程:执行的事件 [begin] ++++++++ //STEP 1 : [线程内容]初始化CFRunLoopSourceContext的空间 bzero(&m_source1_context, sizeof(m_source1_context)); //STEP 2 : [线程内容]调用要执行的函数 m_source1_context.perform = my_do1; //STEP 3 : [线程源]初始化CFRunLoopSourceRef m_source1 = CFRunLoopSourceCreate(NULL, 0, &m_source1_context); //STEP 4 : 将线程源加到当前线程里面去 CFRunLoopAddSource(CFRunLoopGetCurrent(), m_source1, kCFRunLoopCommonModes); //STEP 5 : 执行完,将线程源释放 CFRelease(m_source1); // 第一个线程:执行的事件 [end] ++++++++ // 第二个线程:一个时间计数器,用来启动上面的事件线程 [begin]+++++++++ // STEP 1 初始化时间线程内容空间 bzero(&m_timer1_context, sizeof(m_timer1_context)); // STEP 2 [非常关键] 时间计数器的内容源头是上面的事件源头 m_timer1_context.info = m_source1; // STEP 3 生成时间线程源头句柄 m_timer1 = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 1, 0, 0, timer_function1, &m_timer1_context); // STEP 4 将时间源加入到时间计数列表里面 CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_timer1, kCFRunLoopCommonModes); CFRelease(m_timer1); //第二个线程:一个时间计数器,用来启动上面的事件线程 [end]-------- //如果不用,就会在执行中,可以做其他的事件。但是在DOS环境状态,必须有这一行,在编译时才能看到。 // CFRunLoopRun(); } // STOP - (IBAction)OnBT_Stop:(id)sender { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_source1, kCFRunLoopCommonModes); CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), m_timer1, kCFRunLoopCommonModes); m_Label_Restart.stringValue = @"Stop!"; } - (IBAction)OnBT_SetEveryStartCountNo:(id)sender { m_Label_EveryStartCount_Set.stringValue = m_Edit_SetCurrentNumber.stringValue; g_total_count = [m_Label_EveryStartCount_Set.stringValue intValue]; } - (IBAction)OnBT_CallSelfFunction:(id)sender { [self OnBT_SetEveryStartCountNo:self]; } // Show a MessageBox -(void)Show_Msg { NSAlert *alert = [[[NSAlert alloc] init]autorelease]; [alert setMessageText:@"Label captio is :"]; [alert setInformativeText:@"Close"]; [alert setAlertStyle:NSWarningAlertStyle]; [alert runModal]; } @end
运行效果图:
成功!
需要补充:在定义自身类的时候,一定要初始化 =self,这样才可以使用本身类里面的成员函数或者变量
完成!
特别补充,当你的工程里面加入了iostream等C++代码的时候,就需要将m后缀名修改为mm
这时候就需要将
CFRunLoopSourceSignal((CFRunLoopSourceRef)info);
强制转换1下就可以了。
此语句在m文件里面也可以用。
修改方法,当说不匹配的时候,查找这个函数,发现类型和调用的void不同,就要强制转换。
完。
相关文章推荐
- MAC COCOA一个简单的多线程程序
- MAC COCOA一个简单的多线程程序
- C#多线程编程---一个简单的聊天程序(Server)
- 基于vs2008的一个简单的多线程聊天程序(有界面)
- 一个简单的支持多聊天室的多线程聊天程序
- Cocoa练习01:一个简单的Todo list程序
- C#多线程编程---一个简单的聊天程序(Client)
- 创建一个Mac OS X 下的Cocoa Application对话框程序
- Cocoa练习01:一个简单的Todo list程序
- 一个简单的多线程的大数据信息检索程序
- 【转】一个简单的多线程即时通讯程序(类似QQ,MSN)
- 自己在之前做两个项目中遇到多线程并发访问如何解决的一个简单demo程序
- 创建一个Mac OS X 下的Cocoa Application对话框程序
- selenium:7.一个超级简单的多线程程序
- 一个简单的多线程即时通讯程序(类似QQ,MSN)
- C++实现的一个简单的多线程程序
- MAC下用XCode开发Cocoa程序简单教程
- 网络编程与多线程的应用--基于socket udp编写一个简单聊天程序
- 创建一个MAC OS X下的Cocoa Application对话框程序
- Cocoa练习01:一个简单的Todo list程序