写Python多线程都知道当前线程调用a.join()后,会阻塞直到线程a运行结束,看了一下threading模块的源码,
了解了一下实现的原理。
每一个新开启的线程内部都维护着一个Condition类型的条件变量,对线程a进行join(),其实是wait()在线程a
内部的条件变量上,当线程a执行结束时,会通过notify_all()通知所有join()的线程,则阻塞的线程被唤醒,恢复执行。
以下是源码:
self.__block = Condition(Lock()) #线程内部维护的Contition变量
def __stop(self):
if not hasattr(self, '_Thread__block
继续阅读 »
Java面试总结-线程
1、创建一个线程
创建线程主要分为两个方法
implements Runnable接口并实现run()方法,然后由Runnable对象创建一个Thread对象,调用Tread的start()方法启动线程。
extends Thread 构建一个Thread类的子类,复写run()方法。该方法目前已不再推荐,应该从运行机制上减少需要并行运行的任务数量。
警告:不要调用Thread类或Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,而不会启动新线程??。应该调用Tread.start方法,这个方法将创建一个执行run方法的新线程。
```
/**
* 创建线程的两种方式
继续阅读 »
线程局部存储(Thread Local Storage,TLS)主要用于在多线程中,存储和维护一些线程相关的数据,存储的数据会被关联到当前线程中去,并不需要锁来维护。。
因此也没有多线程间资源竞争问题,那如何去实现TLS存储呢,主要有以下几种方式:
gcc和clang的__thread修饰符
windows下msvc的__declspec(thread)修饰符
pthread库pthread_setspecific和pthread_getspecific接口
windows下的TlsSetValue和TlsGetValue
thread和declspec(thread)的使用
其中thread和declspec(thread)
继续阅读 »
iPhone中的线程应用并不是无节制的,官方给出的资料显示iPhone OS下的主线程的堆栈大小是1M,第二个线程开始都是512KB。并且该值不能通过编译器开关或线程API函数来更改。只有主线程有直接修改UI的能力。
一、线程概述
继续阅读 »
当涉及到耗时的任务时,要用到进度条提示,也就是工作者线程和UI主线程的交互问题。
Andriod提供了几种在其他线程中访问UI线程的方法。
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable, long )
下面给出两个例子分别用handler和runOnUiThread访问UI主线程。
1、使用handler,普通进度条控件
TextView tvShowMessage;
Message message=null;
Handler handler = new Handler() {
public
继续阅读 »
Tornado本身的设计目标是单线程异步非阻塞,要想很好的发挥它的性能最好使用异步IO,并且Tornado本身也提供了异步的AsyncHttpClient的实现,配合gen.coroutine和yield,可以让请求异步执行从而不阻塞当前线程,对于单线程服务器来说,阻塞(blocking)和同步的sleep这种会挂起线程的动作都是服务器的噩梦,因为只有一个线程,所以任何等待都会影响服务器对于其他请求的处理。
异步非阻塞对于第三方IO是http请求的情况还好,毕竟可以使用Tornado提供的异步实现,但是对于有些数据库的IO,则需要异步库的支持,比如针对MongoDB的Motor等。但是第三方异步库的质量也是参差不齐,在实际的工程中
继续阅读 »
也许你会偶然发现Python的多线程程序使用Ctrl-C杀不掉,必须拿到pid用kill -9才能干掉,研究这个问题的原因可以使得对Python多线程的信号处理及线程的退出机制有更好的理解。
假如有一个Python写成的用多线程模拟生产者-消费者的程序,代码如下:
class Producer(threading.Thread):
def run(self):
global count
while True:
if cond.acquire():
if count > 1000:
cond.wa
继续阅读 »
TBOX的线程池通过在每个worker中批量一次拉取多个task,对锁的竞争进行了优化。
由于每个task的函数实现不会太多,所以可以根据每个task的函数地址做hash,统计出每个task执行所花费的平均时间。然后根据这个平均值来动态计算每个worker一次拉取的task的数量,TBOX里面默认每个worker一次拉取10s的task量,这样可以尽可能的避免worker间锁的频繁抢占。
所有从等待队列被拉取出来的task,都会被放到pending队列中去,如果等待队列中的task都被取完了,某个worker处于了空闲状态,就会尝试去pending中,重新拉取其他worker还没有执行到的task, 这样可以解决某些task耗时
继续阅读 »
关于线程同步的一些小记
多线程同步作为基础还是很重要的,在面试中基本作为必备问题,然而在平时的 Android 开发中使用的频率却不是很高,因为一个 synchronized 关键字即可帮我们解决绝大部分情况,但是如果在面试中仅仅回答 synchronized 就略显单薄了,这里记录一下关于多线程同步的一些点。
继续阅读 »
Java日志框架
作为一个Java程序员,肯定离不开日志框架,现在最优秀的Java日志框架是Log4j2,没有之一。根据官方的测试表明,在多线程环境下,Log4j2的异步日志表现更加优秀。在异步日志中,Log4j2使用独立的线程去执行I/O操作,可以极大地提升应用程序的性能。
在官方的测试中,下图比较了Sync、Async Appenders和Loggers all async三者的性能。其中Loggers all async表现最为出色,而且线程数越多,Loggers all async性能越好。
除了对Log4j2自身的不同模式做对比以外,官方还做了Log4j2/Log4j1/Logback的对比,如下图所示
其
继续阅读 »