浅谈线程(thread)

2019-07-14 11:04发布

什么是线程呢?线程和进程又有什么区别和联系呢?
   线程是进程的一个执行分支,线程在进程内部运行(指的是线程在进程的虚拟地址空间内运行)。在Linux中,内核看到的线程也是PCB来表示,创建的新PCB和·原PCB共用相同的虚拟地址空间。Linux中用进程来模拟线程,这种线程也称为轻量级进程(LWP),统一了进程和线程的管理。一个进程可以并发多个线程,每个线程并行执行多个任务。线程的存在是为了并发执行提高效率,但多进程也可以达到同样的目的,那为什么要存在线程呢?现在来谈谈线程的优点:首先,因为线程创建是共享地址空间的,所以创建一个线程的代价比创建一个进程小得多,同样的,销毁一个线程的代价也比销毁一个进程小得多。其次,与进程之间的切换相比,线程之间切换需要操作系统做的工作少很多。另外因为进程是相互独立的,所以进程之间的资源不共享,进程要想进行资源共享,必须用进程通信来实现。相对而言,线程共享数据更容易。但是线程也有缺点,比如:缺乏访问控制,一个线程崩溃可能引起其它线程崩溃,导致此进程挂掉。而且编写与调试一个多线程程序比单线程程序困难得多。   线程之间共享同一地址空间,共享文件描述符表(线程1打开了一个文件,其它线程也能看到),线程虽然是资源共享的,但是也有自己私有的,比如线程拥有独立的调用栈,因为线程需要切换,所以线程需要有自己独立的上下文信息,线程也有自己独立的线程·id.

下边我们来实现线程控制(线程创建,销毁,等待以及分离):
  进程是用系统调用来实现进程控制的,而在Linux下内核不区分进程和线程,所以,关于线程的各种操作,操作系统不直接提供接口,而是以库函数提供(Posix线程库)。      线程创建:然后来编写Makefile:(注意:在链接这些线程函数库的时候,要是用编译器命令的-lpthread选项)运行结果:我们发现两个线程的pid一样,但线程id不一样,说明是在同一个进程内部的两个不同线程,是个多线程程序。此时我们也可以再开一个终端用命令来查看线程,命令行敲入:ps -aL | grep thread就可查看我们此时tjread中的线程,也可以使用gdb及将gdb附加到此进程上,进行进程调试。(如:gdb attach 17311).
  线程终止:如果需要终止某个线程而不是整个进程,可以有以下三种方法;  1 从线程函数return,这种方法不适合主线程,从main函数return相当于调用exit.  2 线程可以调用pthread_exit终止自己。而我们以前学的exit是用来终止整个进程。  3 一个线程可以调用pthread_cancel终止同一进程中的另一个线程。此时线程被取消,退出码为-1. 如:i am thread 1 thread:3077741424 pid:17391
thread done
-1
线程等待:为什么要进行进程等待呢?因为如果不进行线程等待可能会造成类似僵尸进程的现象,会造成内存泄漏的问题。如上进程等待的代码:     我们看到的现象是thread1先打印,随后3s thread1退出,主线程再进行打印。说明是阻塞式等待,并得到返回值为1.
线程分离:     什么是线程分离呢?默认情况下:新创建的线程的属性为:可结合的,线程退出后,需要进行join,如果不等待就会造成无法释放资源,进而造成内存泄漏。而我们如果不关心线程对的返回值,join是一种负担,这个时候我们可以将线程设为分离状态,句相当于告诉系统,当线程退出时,自动释放线程资源,此时线程再进行等待就会失败。结果: