iOS开发之多线程笔记(二)之pthread
2018-01-10 本文已影响21人
番茄炒西红柿啊
pthread在中使用不多,我这个小码农也是偶然间才在网上看到的,于是就浅显的了解了一下.介绍概念什么的请自行Google.这里直接开始撸代码
- 这里模拟一个场景,开启4个线程去同时操作一个整数,将其减一,直到减到0.
oc 代码如下
#pragma mark - Event Response
- (void)pThread_test {
self.count = 1000;
for(int i = 0; i < 4; i++) {
[self create_pThread];
}
}
- (void)create_pThread {
//创建线程对象
pthread_t thread;
//创建线程
/*
参数:
1.指向线程标识符的指针,C 语言中类型的结尾通常 _t/Ref,而且不需要使用 *;
2.用来设置线程属性;
3.指向函数的指针,传入函数名(函数的地址),线程要执行的函数/任务;
4.运行函数的参数;
*/
int success = pthread_create(&thread, NULL, run, &(_count));
if(success == 0) {
/*
c语言中,有时成功及成功,错误却会有很多种原因
所以这里返回0表示开辟线程成功
非0表示失败开启线程失败
*/
NSLog(@"开启线程...");
}
//这里需要手动设置子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源.否则不会释放.
pthread_detach(thread);
}
void *run(void* sender) {
while (1) {
int* s = sender;
int count = *s;
if(count <= 0) {
break;
}
test(s);
}
return NULL;
}
void test(int *count) {
*count = *count - 1;
NSLog(@"%d", *count);
}
1.pngok代码就这样,看起来貌似没问题.cmd+R
结果有点不遂人愿.这里有2个子线程对count操作后,返回的结果却是一样的.这就和我们所需要的逻辑不和了.我们所期望的是每一个线程做完减一操作后,下一个线程再来操作应该是在减一的基础上减一.所以是不可以出现2个线程都操作完之后结果是一样的场景.此结果也不符合逻辑.
这就是我们常说要注意的线程安全问题 有个变量,你在一个线程中修改它的值,同时在另一个线程中也改了它的值.这个时候你再去读这个值的时候,很可能这个值,就不是你所预期的了.
这里我们需要给run这个方法内部添加一个线程锁,来保证一次只能有一个线程进入来操作数据
void *run(void* sender) {
if(!condition) {
condition = [[NSCondition alloc] init];
}
while (1) {
[condition lock];
int* s = sender;
int count = *s;
if(count <= 0) {
[condition unlock];
break;
}
test(s);
[condition unlock];
}
return NULL;
}
加锁的方式有很多,以后再专门总结一下,这里暂时就用这一种.加锁后,结果就和预期的一样了.
- 使用pThread时需要导入头文件 #import <pthread.h>
- 参考:
iOS开发 - 多线程实现方案之Pthread篇
iOS多线程中的实际方案之一pthread
swift相关代码在网上相关介绍不多,自己倒腾了下,顺便贴上swift代码:
let run : @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? =
{ (pktlist:UnsafeMutableRawPointer) in
while true {
condition.lock()
let p:UnsafeMutableRawPointer = pktlist
let t = p.assumingMemoryBound(to: Int.self)
guard t.pointee > 0 else {
condition.unlock()
break;
}
t.pointee -= 1;
NSLog("%d", t.pointee)
condition.unlock()
}
return nil
}
@objc private func pThread_test() -> Void
{
self.count = 1000
for i in 0..<4
{
if i < 4
{
let pthread: UnsafeMutablePointer<pthread_t?> = UnsafeMutablePointer<pthread_t?>.allocate(capacity: MemoryLayout<pthread_t?>.size)
let param = UnsafeMutableRawPointer(&count)
let success = pthread_create(pthread, nil, self.run, param)
if success == 0 {
NSLog("开启线程...")
}
pthread_detach((pthread.pointee)!)
pthread.deinitialize()
pthread.deallocate(capacity: MemoryLayout<pthread_t?>.size)
}
}
}
- 这里涉及到了swift中的指针,和将方法转成c语言的函数指针.
具体请看Swift指针 Swift方法转换成c语言指针