美文网首页
iOS开发之多线程笔记(二)之pthread

iOS开发之多线程笔记(二)之pthread

作者: 番茄炒西红柿啊 | 来源:发表于2018-01-10 13:54 被阅读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);
    }
    

    ok代码就这样,看起来貌似没问题.cmd+R

    1.png
    结果有点不遂人愿.这里有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;
    }
    

    加锁的方式有很多,以后再专门总结一下,这里暂时就用这一种.加锁后,结果就和预期的一样了.

    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)
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:iOS开发之多线程笔记(二)之pthread

          本文链接:https://www.haomeiwen.com/subject/jwognxtx.html