为什么样会有“线程是为不懂状态机的程序员准备的”这种说法?linux:多线程进程比单线程进程的性能要差
如果单纯追求性能的话,单核CPU上是不需要多线程。但是,
在多线程模式下我们可以使用阻塞IO,①个简单的逻辑如下:
//输入-〉计算-〉输出
input_result = input();
compute_result = compute(input_result);
output(compute_result);
或:
output(compute(input()));
而单线程模式下,如果要处理多个请求,不能使用阻塞IO,你需要这样写:
function compute_callback(compute_result){output(compute_result);}
function input_callback(input_result){compute(input_result,compute_callback);}
input(input_callback);
或这样写:
while((msg=GetMessage())!=QUIT)
{
switch(msg)
{
case PROGRAM_START:input();break;
case INPUT_COMPLETE: compute(msg);break;
case COMPUTE_COMPLETE:output(msg);break;
case OUTPUT_COMPLETE:post_quit_message();break;
...
}
}
不但代码复杂,而且无法清晰、连贯的表达业务逻辑,可读性差。你无法直接梳理出“输入-〉计算-〉输出”这样的逻辑顺序。
不止是开发困难、可读性差,单线程/非阻塞IO下的程序是通过各种事件派发来调度的,出问题调试起来更要命。
所以,多线程阻塞IO模式下的编程会给你带来很多方便,除非你有更高的性能要求或处理大量并发,使用多线程/阻塞IO是更好的选择。即使是单CPU,多线程阻塞IO也有他的价值。
PS:也有更灵活的折中方案,如tomcat等web服务器普遍采用半同步/半异步的方式,①个(或少数几个线程)使用非阻塞IO监听网络请求,然后派发到线程池,使用阻塞IO同步处理。
代码:
static volatile unsigned long op[①⓪⓪];
static volatile int g_rand = ⓪;
static volatile unsigned long pre_op[①⓪⓪];
/*用于测试的不同锁*/pthread_mutex_t g_mutex[①⓪⓪];pthread_rwlock_t g_mutex_rw[①⓪⓪];pthread_spinlock_t g_spinlock[①⓪⓪];/*⑤⓪⓪W的Hash表*/#define HASH_SIZE (⑤*①⓪②④*①⓪②④)static unsigned int *g_hash[③②];/*测试线程static void *thread_select(void *arg){int i = * (int *)arg;printf(\"thread:%dn\",i); cpu_set_t mask; cpu_set_t get; char buf[②⑤⑥]; int num = sysconf(_SC_NPROCESSORS_CONF); printf(\"system has %d processor(s)n\", num); CPU_ZERO( CPU_SET(i, /*设置线程的CPU亲缘性。 */// if (pthread_setaffinity_np(pthread_self(), sizeof(mask), // }// unsigned int obj = rand();while(①){/***①.是否加锁****///pthread_mutex_lock(//pthread_spin_lock(//pthread_rwlock_rdlock(//time(NULL);//rand();//操作计数op[i] ++;unsigned int obj = g_rand;memcmp(//pthread_rwlock_unlock(//pthread_spin_unlock(//pthread_mutex_unlock(}}/*打印线程*/void *thread_print(void *arg){ int n; while(①) { /*打印前④个线程当前总的操作计数*/ // printf(\"op[③]:%lun\",op[③]); printf(\"thread⓪_op_times: %lu ppsthread①_op_times: %lu ppsthread②_op_times: %lu pps thread③_op_times: %lu ppsn\", op[⓪], op[①] ,op[②], op[③] ); unsigned long all_op = ⓪; int j = ⓪; for(j = ⓪ ;j < ③②; j ++) {// pthread_mutex_lock( all_op += (op[j] - pre_op[j]); pre_op[j] = op[j]; // pthread_mutex_unlock( } /*打印休眠周期内的总操作次数*/ printf(\"all_op:%lun\", all_op ); all_op = ⓪; /*休眠*/ sleep(①⓪);// usleep(①⓪⓪⓪ * ⑨⑨⓪); } return NULL;}void *thread_rand(void *arg){while(①){g_rand = rand();}}int main(void){pthread_t t[④⓪]; int i = ⓪; int thread_id[③②]; int total_num = ⓪; /*初始化随机数种子 */ srand(time(NULL)); /*初始化锁与计数 *//*启动随机数生成线程*/pthread_create( for( i = ⓪ ; i < ③②; i ++) { op[i] = ⓪; pre_op[i] = ⓪; pthread_mutex_init( pthread_rwlock_init( pthread_spin_init( g_hash[i] = (unsigned int *)malloc( sizeof(unsigned int ) * HASH_SIZE ); memset(g_hash[i],⓪ · sizeof(unsigned int ) * HASH_SIZE ); }printf(\"start create thread_selectn\");/*线程优先级*/struct sched_param param;param.__sched_priority = ②⓪;pthread_attr_t attr;pthread_attr_init(pthread_attr_setinheritsched(pthread_attr_setschedpolicy(pthread_attr_setschedparam(/*启动打印线程*/pthread_create(/*线程编号*/ for( i=⓪;i
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息