当用c++编程的时候,如果使用多线程,那么确实进程cpu超过100%非常正常,但是对python来说,似乎这样就和网上的文章冲突了。
所以还是决定自己亲身试验一下,编写代码如下:
from thread import start_new_thread
def worker():
while 1:
#print 1
pass
for it in range(0, 15):
start_new_thread(worker, ())
raw_input()
运行环境为: centos6.4 64位, python 2.7.
得到的结果如下:
可以清楚的看到,pid为31199的python进程cpu达到了787.9%,接近理论能达到的最大值 800%。
而上方的8个cpu也分别达到了近100%的利用率。
如果只是按照以上测试结果,确实可以得出的结论:python使用单进程,多线程确实能够使用到多核cpu,并不是网上传的结论。
但是,还是希望如果有读者对这块有更深入的研究能够进行批评指正,谢谢~
感谢 la.onger 等几位博友的讨论,现在增加一个测试,用来测试纯cpu计算用一个线程or多个线程完成的总时间的差别,代码如下:
import time
from threading import Thread
LOOPS = 1000000
THREAD_NUM = 10
STEP_SIZE = 94753434
class Test(object):
num = 1
def work(self):
for it in xrange(0, LOOPS):
if self.num > STEP_SIZE:
self.num -= STEP_SIZE
else:
self.num += STEP_SIZE
def one_thread_test(self):
self.num = 1
begin_time = time.time()
for v in xrange(0, THREAD_NUM):
self.work()
print 'time passed: ', time.time() - begin_time
def multi_thread_test(self):
self.num = 1
t_list = []
begin_time = time.time()
for v in xrange(0, THREAD_NUM):
t = Thread(target=self.work)
t.start()
t_list.append(t)
for it in t_list:
it.join()
print 'time passed: ', time.time() - begin_time
t = Test()
t.one_thread_test()
t.multi_thread_test()
输入结果如下:
time passed: 3.44264101982
time passed: 7.22910785675
使用多线程后,比不用多线程还慢
为了与c++版做对比,也开发了c++代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LOOPS 1000000
#define THREAD_NUM 10
#define STEP_SIZE 94753434
class Test
{
public:
Test() {}
virtual ~Test() {}
void one_thread_test() {
this->num = 1;
gettimeofday(&m_tpstart,NULL);
for (size_t i = 0; i < THREAD_NUM; ++i)
{
work();
}
gettimeofday(&m_tpend,NULL);
long long timeuse=1000000*(long long)(m_tpend.tv_sec-m_tpstart.tv_sec)+m_tpend.tv_usec-m_tpstart.tv_usec;//微秒
printf("time passed: %fn", ((double)timeuse) / 1000000);
}
void multi_thread_test() {
this->num = 1;
int ret;
vector
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
gettimeofday(&m_tpstart,NULL);
pthread_t threadId;
for (int i = 0; i < THREAD_NUM; i++)
{
ret= pthread_create(&threadId, &attr, Test::static_run_work, (void*)this);
if(ret!=0){
pthread_attr_destroy (&attr);
}
vecThreadId.push_back(threadId);
}
pthread_attr_destroy (&attr);
for(vector
{
pthread_join(*it, NULL);
}
gettimeofday(&m_tpend,NULL);
long long timeuse=1000000*(long long)(m_tpend.tv_sec-m_tpstart.tv_sec)+m_tpend.tv_usec-m_tpstart.tv_usec;//微秒
printf("time passed: %fn", ((double)timeuse) / 1000000);
}
void work() {
for (size_t i = 0; i < LOOPS; ++i) {
if (this->num > STEP_SIZE) {
this->num -= STEP_SIZE;
}
else {
this->num += STEP_SIZE;
}
}
}
static void* static_run_work(void *args) {
Test* t = (Test*) args;
t->work();
return NULL;
}
public:
int64_t num;
struct timeval m_tpstart,m_tpend;
};
int main(int argc, char **argv)
{
Test test;
test.one_thread_test();
test.multi_thread_test();
return 0;
}