Skip to content

Instantly share code, notes, and snippets.

@Neko3000
Last active September 21, 2020 05:52
Show Gist options
  • Save Neko3000/99488af93758d43f04ecfc3e863873f6 to your computer and use it in GitHub Desktop.
Save Neko3000/99488af93758d43f04ecfc3e863873f6 to your computer and use it in GitHub Desktop.
import UIKit
extension Thread{
public func join(){
while(!self.isFinished){
usleep(10)
}
}
public func state() -> String{
var state: String = ""
if(self.isExecuting){
state = "isExecuting"
}
else if(self.isFinished){
state = "isFinished"
}
else if(self.isCancelled){
state = "isCancelled"
}
return state
}
}
class TestUnitA: NSObject{
var thread1 : Thread?
var thread2 : Thread?
override init() {
super.init()
}
@objc func threadProc(){
print("\nCurrent thread: \(Thread.current.name ?? "none") started");
for i in 1...10{
if (Thread.current.name == "Thread1"){
if(self.thread2 != nil && self.thread2!.isExecuting){
thread2!.join();
}
}
print("Current thread: \(Thread.current.name ?? "none") outputs \(i)")
sleep(1)
}
usleep(10)
print("Current thread: \(Thread.current.name ?? "none") after loop");
print("Thread1: \(thread1!.state())");
print("Thread2: \(thread2!.state())");
print("Current thread: \(Thread.current.name ?? "none") finished\n");
}
public func run(){
self.thread1 = Thread(target: self, selector: #selector(threadProc), object: nil)
thread1!.name = "Thread1"
thread1!.start()
sleep(5)
self.thread2 = Thread(target: self, selector: #selector(threadProc), object: nil)
thread2!.name = "Thread2"
thread2!.start()
}
}
let testUnit = TestUnitA()
testUnit.run()
import UIKit
class JoinableThread: NSObject{
public var name:String?
public var isExecuting:Bool{
return self.thread!.isExecuting
}
public var isCancelled:Bool{
return self.thread!.isCancelled
}
public var isFinished:Bool{
return self.thread!.isFinished
}
private var thread:Thread?
private var target:AnyObject?
private var selector:Selector?
private var arguments:AnyObject?
private let runLoopMode:RunLoop.Mode = RunLoop.Mode.init(rawValue: "joinMe")
init(target:AnyObject ,selector:Selector, arguments:AnyObject?) {
super.init()
self.thread = Thread(target: self, selector: #selector(beforeTask), object: nil)
self.target = target
self.selector = selector
self.arguments = arguments
}
@objc public func beforeTask() {
if(self.thread!.isCancelled){
return
}
// ???: 这步让我疑惑,在iOS7.0+,似乎线程一开始以后就自动创建了autoreleasepool
// https://stackoverflow.com/questions/24952549/does-nsthread-create-autoreleasepool-automatically-now
autoreleasepool{
Thread.current.name = self.name
autoreleasepool{
if(self.target!.responds(to: self.selector!)){
self.target!.perform(self.selector!, with: arguments ?? nil)
}
}
RunLoop.current.add(Port(), forMode: self.runLoopMode)
RunLoop.current.run(mode: self.runLoopMode, before: Date.distantFuture)
}
}
@objc public func finishJoin(){
print("join finished");
}
public func join() -> Bool{
if(!self.thread!.isFinished){
self.perform(#selector(finishJoin), on: self.thread!, with: nil, waitUntilDone: true, modes: [self.runLoopMode.rawValue])
return true
}
return false
}
public func start(){
self.thread!.start()
}
public func state() -> String{
var state: String = ""
if(self.thread!.isExecuting){
state = "isExecuting"
}
else if(self.thread!.isFinished){
state = "isFinished"
}
else if(self.thread!.isCancelled){
state = "isCancelled"
}
return state
}
}
class TestUnitB: NSObject{
var joinableThread1 : JoinableThread?
var joinableThread2 : JoinableThread?
override init() {
super.init()
}
@objc func threadProc(){
print("\nCurrent thread: \(Thread.current.name ?? "none") started");
for i in 1...10{
if (Thread.current.name == "Thread1"){
if(self.joinableThread2 != nil && self.joinableThread2!.isExecuting){
joinableThread2!.join();
}
}
print("Current thread: \(Thread.current.name ?? "none") outputs \(i)")
sleep(1)
}
usleep(10)
print("Current thread: \(Thread.current.name ?? "none") after loop");
print("Thread1: \(joinableThread1!.state())");
print("Thread2: \(joinableThread2!.state())");
print("Current thread: \(Thread.current.name ?? "none") finished\n");
}
public func run(){
self.joinableThread1 = JoinableThread(target: self, selector: #selector(threadProc), arguments: nil)
joinableThread1!.name = "Thread1"
joinableThread1!.start()
sleep(5)
self.joinableThread2 = JoinableThread(target: self, selector: #selector(threadProc), arguments: nil)
joinableThread2!.name = "Thread2"
joinableThread2!.start()
}
}
let testUnit = TestUnitB()
testUnit.run()
for (;![self.thread isFinished];) {
// 要是没结束就休眠!!
usleep(2);
}
using System;
using System.Threading;
public class Example
{
static Thread thread1, thread2;
public static void Main()
{
thread1 = new Thread(ThreadProc);
thread1.Name = "Thread1";
thread1.Start();
thread2 = new Thread(ThreadProc);
thread2.Name = "Thread2";
thread2.Start();
}
private static void ThreadProc()
{
Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
if (Thread.CurrentThread.Name == "Thread1" &&
thread2.ThreadState != ThreadState.Unstarted)
thread2.Join();
Thread.Sleep(4000);
Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
Console.WriteLine("Thread1: {0}", thread1.ThreadState);
Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
}
}
// The example displays output like the following:
// Current thread: Thread1
//
// Current thread: Thread2
//
// Current thread: Thread2
// Thread1: WaitSleepJoin
// Thread2: Running
//
//
// Current thread: Thread1
// Thread1: Running
// Thread2: Stopped
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment