您的位置:控制工程论坛网论坛 » 嵌入式系统 » Linux下编写多线程介绍

zhiy66

zhiy66   |   当前状态:在线

总积分:6528  2025年可用积分:0

注册时间: 2007-12-18

最后登录时间: 2012-01-11

空间 发短消息加为好友

Linux下编写多线程介绍

zhiy66  发表于 2008/11/20 10:15:16      1018 查看 0 回复  [上一主题]  [下一主题]

手机阅读

(一)多线程特点  

    进程是系统中程序执行和资源分配的基本单位,每个进程都有自己的数据段,代码段和堆栈段,这就使得进程在进行切换等操作时需要有上下文切换动作,为了减少上下文切换开销,进程在演化过程中出现了另外一个概念,就是线程。它是一个进程内的基本调度单位,也可以称为轻量级进程。

    使用多线程是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。

    另外,使用多线程可以方便线程间的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。

    多线程程序同样具有作为一种多任务、并发的工作方式的优点:
  1) 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)启动一个新的线程去执行,可以避免这种瓶颈对系统响应速度的影响。
  2) 使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
  3) 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。

   (二) 多线程编程

    1、线程的创建与退出

创建线程实际上就是确定调用该线程的函数入口点,通常使用函数: pthread_create

在线程创建后,就开始运行相关的线程函数,在该函数运行完后,线程也就退出了,若想在线程函数结束之前提前退出,可使用函数: pthread_exit

其中:pthread_create函数原型为:

int  pthread_create(pthread_t  *thread,pthread_attr_t *attr,void*(*start_routine)(void*),void *arg)

参数介绍:thread:线程标识符

                 attr:线程属性设置,NULL默认为joinable属性,线程在执行完毕后不会立即被Linux清除,如果函数有返回值,其返回值可以通过调用函数pthread_join()得到。

      *start_routine:指向新线程所要执行的函数指针。

                      arg:传递给新线程的参数。

 

pthread_exit函数原型: void pthread_exit(void *retval)

参数介绍: Retval:调用pthread_exit()线程函数的返回值,可由函数:pthread_join来检索获取。

 

pthread_join函数原型:int  pthread_join(pthread_t th,void **thread_reaturn)

参数介绍: th:等待线程的标识符。

 thread_return:用户定义的指针,当不为NULL时,用来存储被等待线程的返回值。

2、上机实验举例

/***expriment.c****/

# include<stdio.h>

#i nclude<pthread.h>

/***线程一***/

void  task1(void)

{

       int     i=0;

      for(i=0;i<3;i++)

      {

           printf("This is thread1.\n");

          if(i==2)

              pthread_exit(0);

              sleep(1);

        }

}

/***线程二***/

void   task2(void)

{

     int      i;

     for(i=0;i<3;i++)

         printf("This is thread2.\n“)

         pthread_exit(0);

}

int    main(void)

{

         pthread_t      id1,id2;

               int             i,ret;

   /***创建线程一***/

      ret=pthread-create(&id1,NULL,(void *) task1,NULL );

      if (ret!=0)

        {

                  printf("create pthreaed error!\n“);

                   exit(1);

         }

/***创建线程二***/

      ret=pthread_create(&id2,NULL,(void *) task2,NULL)

     if(ret!=0)

    {

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

          exit(1);

    }

/***等待线程结束***/

       pthread_join(id1,NULL);

       pthread_join(id2,NULL);

      exit(0);

}     

以下是实验运行结果:

     [root@Caiwm  expriment]# ./expriment

This  is   thread1.

This  is   thread2.

This  is   thread2.

This  is   thread2.

This  is   thread1.

This  is   thread1.

1楼 0 0 回复