下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

Linux下 多线程与多进程的优劣比较

作者:课课家教育     来源: http://www.kokojia.com点击数:1579发布时间: 2016-02-22 11:49:19

标签: Linux多线程linux系统Linux

  一、多线程 VS 多进程

  和进程相比,线程有很多优势。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护代码段和数据。而运行于一个进程中的多个线程,他们之间使用相同的地址空间。正是这样,同一进程下的线程之间共享数据空间,数据可以相互使用,并且线程间切换也要更快些,可以更有效的利用CPU。

Linux下 多线程与多进程的优劣比较_Linux多线程_linux系统_Linux_课课家

  二、程序设计

  [注] 头文件 编译时要加载动态库 libpthread.a,使用 -lpthread

  1、创建线程

  2、等待线程

  3、关闭线程

  4、退出清除

  1、创建线程

  int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void), void *arg)

  tidp为线程id,是函数分配的值,所以要传一个 pthread_t 的地址。

  attr线程属性,通常为空。

  start_rtn为线程要执行的函数,返回值为空指针,参数为后面的*arg

  若成功则返回0,否则返回出错编号。

  例:

  #include

  #include

void *func1(void *arg){ //原函数声明

  int i;

  for(i=0;i<5;i++){

  printf("this is func1! The num is %d\\n",*(int*)arg); //将空指针转换为int型指针

  sleep(1);

  }

  }

void *func2(int *m){ //自定义类型声明,也可以定义非指针类型,但是在create时会有警告,因为非地址并不能改变传入的值

  int i;

  for(i=0;i<5;i++){

  printf("this is func2! The num is %d\\n",*m);

  (*m)++;

  sleep(1);

  }

  }

int main(){

  pthread_t id1,id2;

  int num = 5;

  int *p = &num;

  if(pthread_create(&id1,NULL,(void *)func1,(void *)p) != 0){

  printf("thread1 create error!\\n");

  return -1;

  }

  if(pthread_create(&id2,NULL,(void *)func2,&num) != 0){

  printf("thread2 create error!\\n");

  return -1;

  }

  pthread_join(id1,NULL); //等待线程结束

  pthread_join(id2,NULL);

  printf("Running complete!\\n");

  return 0;

  }

  运行结果:

  [fsy@localhost process]$ gcc thC.c -o thC -lpthread -g

  [fsy@localhost process]$ ./thC

  this is func2! The num is 5

  this is func1! The num is 6

  this is func2! The num is 6

  this is func1! The num is 7

  this is func2! The num is 7

  this is func1! The num is 8

  this is func2! The num is 8

  this is func1! The num is 9

  this is func2! The num is 9

  this is func1! The num is 10

  Running complete!

  [fsy@localhost process]$

  2、等待线程

  [注]当调用pthread_create函数时,线程并没有开始执行,主进程应有等待,比如用sleep,或者用更专业的函数:pthread_join

  int pthread_join(pthread_t tid, void **rval_ptr)

  调用函数可以阻塞调用线程,直到指定的线程终止。

  tid为等待退出线程的id,rval_ptr为函数的返回值。是指向指针的指针,可以置空。

  例:

  #include

  #include

  #include

void *func(int *p){

  int *num=(int *)malloc(sizeof(int)); //必须动态创建,原因可以参考我动态分配内存的博客

  printf("Please input the number: ");

  scanf("%d",num);

  return (void *)num; //类型是pthread_create的参数规定的

  }

int main(){

  pthread_t pth;

  void *a;

  if(pthread_create(&pth,NULL,(void *)func,NULL) != 0){

  printf("create thread error!\\n");

  return 1;

  }

  pthread_join(pth,&a); //指向空指针的指针

  printf("get the num from the thread, it's %d\\n",*(int *)a);

  return 0;

  }

  3、终止线程

  线程终止有以下三种方式:

  1、线程从函数中返回

  2、线程可以别其他函数终止

  3、线程自己调用pthread_exit函数

  void pthread_exit(void *rval_ptr)

  rval_ptr为线程退出返回值的指针,即函数返回值。

  4、退出清除

  void pthread_cleanup_push(void (*rtn)(void*), void *arg)

  rtn为清除函数,arg是清除函数的参数

  void pthread_cleanup_pop(int execute)

  当execute 非0时执行清除函数。为0时不执行。

  从pthread_cleanup_push的调用点到pthread_cleanup_pop之间的程序段中,如果有终止进程的动作,如调用pthread_exit或异常终止(不包括return),就会执行pthread_cleanup_push()所指定的清理函数。多个嵌套匹配时,就近匹配。

  例:

  #include

  #include

void *clean(char *argv){

  printf("clean is called by %s\\n",argv);

  return NULL;

  }

  void *func1(void *argv){

  printf("welcome enter the func1!\\n");

  pthread_cleanup_push((void*)clean,"the first time call!");

  pthread_cleanup_push((void*)clean,"the second time call!");

  if(argv){

  return (void *)1; //第二次运行将此句注掉

  }

  pthread_cleanup_pop(0);

  pthread_cleanup_pop(1);

  return (void *)0;

  }

void *func2(void *argv){

  sleep(1); //两个线程运行先后不确定

  printf("welcome enter the func2!\\n");

  pthread_cleanup_push((void*)clean,"the first time call!");

  pthread_cleanup_push((void*)clean,"the second time call!");

  if(argv){

  pthread_exit(NULL);

  }

  pthread_cleanup_pop(0);

  pthread_cleanup_pop(0);

  return (void *)0;

  }

  int main(){

  pthread_t tid1,tid2;

  if(pthread_create(&tid1,NULL,(void *)func1,(void *)1) != 0){

  printf("thread1 create error!\\n");

  return 1;

  }

if(pthread_create(&tid2,NULL,(void *)func2,(void *)1) != 0){

  printf("thread2 create error!\\n");

  return 1;

  }

  pthread_join(tid1,NULL);

  pthread_join(tid2,NULL);

  return 0;

  }

  运行结果:

  [fsy@localhost process]$ gcc thClean.c -o thclean -lpthread

  [fsy@localhost process]$ ./thclean

  welcome enter the func1!

  welcome enter the func2!

  clean is called by the second time call! //此处先2后1

  clean is called by the first time call!

  [fsy@localhost process]$ vim thClean.c

  [fsy@localhost process]$ gcc thClean.c -o thclean -lpthread

  [fsy@localhost process]$ ./thclean

  welcome enter the func1!

  clean is called by the first time call! //second已经被pop

  welcome enter the func2!

  clean is called by the second time call!

  clean is called by the first time call!

  [fsy@localhost process]$

赞(25)
踩(4)
分享到:
华为认证网络工程师 HCIE直播课视频教程