⑴ 有人能教下我有关linux里面线程的知识吗
.线程的基本介绍
(1)线程的概述
线程与进程类似,也允许应用程序并发执行多个任务的一种机制。一个进程可以包含多个线程,同一程序中的所有线程共享同一份全局内存区域,线程之间没有真正意义的等级之分。同一个进程中的线程可以并发执行,如果处理器是多核的话线程也可以并行执行,如果一个线程因为等待I/O操作而阻塞,那么其他线程依然可以继续运行
(2)线程优于进程的方面
argv,environ
主线程栈
线程3的栈
线程2的栈
线程1的栈
共享函数库共享的内存
堆
未初始化的数据段
初始化数据段
文本
.进程间的信息难以共享。由于除去只读代码段外,父子进程并未共享内存,因此必须采用一些进程间通讯,在进程之间交换信息
.调用fork()来创建进程代价相对较高
线程很好的解决了上述俩个问题
.线程之间能够方便,快速的共享信息,只需将数据复制到共享(全局或堆)变量中即可
.创建线程比创建线程通常要快10甚至更多,线程创建之所以快,是因为fork创建进程时所需复制多个属性,而在线程中,这些属性是共享的。
(3)创建线程
启动程序时,产生的进程只有单条线程,我们称之为主线程
#include<pthread.h>
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*start)(void *),void *arg);12
新线程通过调用带有arg的函数开始执行,调用pthread_create()的线程会继续执行该调用之后的语句。
(4)终止线程
可以以如下方式终止线程的运行
.线程调用pthread_exit()
.线程start函数执行return语句并返回指定值
.调用pthread_cancel()取消线程
.任意线程调用了exit(),或者主线程执行了return语句,都会导致进程中的所有线程立即终止
pthread_exit()函数可以终止线程,且其返回值可由另一线程通过调用pthread_join()获得
#include<pthread.h>void pthread_exit(void *retval);12
调用pthread_exit()相当于在线程的start函数中执行return,不同之处在于,pthread_exit()可以在任何地方调用,参数retval指定了线程的返回值
(5)获取线程ID
#include<pthread.h>pthread_t pthread_self(void);12
线程ID在应用程序中主要有如下用途
.不同的pthreads函数利用线程ID来标识要操作目标线程。
.在具体的应用程序中,以特定线程的线程ID作为动态数据结构的标签,这颇有用处,既可用来识别某个数据结构的创建者或属主线程,又可确定随后对该数据结构执行操作的具体线程
函数pthread_equal()可检查俩个线程的ID是否相同
#include<pthread.h>int pthread_equal(pthread_t t1,pthread_t t2);//如果相同返回非0值,否则返回0123
(6)连接已终止的线程
函数pthread_join()等待由thread表识的线程终止
#include<pthread.h>int pthread_join(pthread_t thread,void **retval);//返回0调用成功,否则失败123
如果pthread_join()传入一个之前已然连接过的线程ID,将会导致无法预知的行为,当相同线程ID在参与一次连接后恰好为另一新建线程所重用,再度连接的可能就是这个新线程
若线程未分离,则就应该使用pthread_join()来连接线程,否则会产生僵尸线程
pthrea_join()函数的要点
.线程之间的关系是对等的,所以任意线程都可以调用pthread_join()来连接其他线程
.pthread_join()无法针对任意线程,只能连接单个线程
(6)线程的分离
默认情况下线程都是可连接的,但有时候,我们并不关心线程退出的状态,我们可以调用pthread_detach()并向thread参数传入指定线程的的标识符,将该线程标记为处于分离状态
#include<pthread.h>int pthread_detach(pthread_t thread);//返回0成功,否则失败123
一旦线程处于分离状态,就不能在使用pthread_join()来获取其状态,也无法使其重返可连接状态
(7)在应用程序中如何来选择进程还是线程
.线程之间共享数据很简单,进程间的数据共享需要更多的投入
.创建线程要比创建进程块很多
.多线程编程时,需要确保调用线程安全的函数
.某个线程中的bug可能会危害进程中所有线程
.每个线程都在征用宿主进程中有限的虚拟地址空间
.在多线程应用中,需要小心使用信号
.除了数据,线程还可以共享文件描述符,信号处置,当前工作目录,以及用户ID和组ID
线程的同步
(1)保护共享变量访问:互斥量
线程的主要优势在于能够通过全局变量来共享信息,不过这种共享是有代价的。必须确保多个线程修改同一变量时,不会有其他线程也正在修改此变量,为避免线程更新时共享变量时所出现的问题,必须使用互斥量来确保同时仅有一个线程可以访问某项共享资源
(2)静态分配的互斥锁
互斥锁既可以像静态变量那样分配,也可以在运行时动态分配,互斥量属于pthread_mutex_t类型的变量,在使用之前必须对其初始化。对于静态分配的互斥量而言,可如下例所示,将PTHREAD_MUTEX_INITIALIZER赋给互斥量
pthread_mutex_t = PTHREAD_MUTEX_INITIALIZER;1
1.加锁和解锁互斥量
初始化之后,互斥量处于未锁定状态。函数pthread_mutex_lock()可以锁定某一互斥量
而函数pthread_mutex_unlock()则可以将一个互斥量解锁
#include<pthread.h>int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);//返回0成功,其他失败1234
要锁定互斥量,在调用pthread_mutex_lock()时需要指定互斥量,如果互斥量当前处于未锁定状态,则该调用将会立即返回,如果该互斥量已被其他线程锁定,那么该调用将会阻塞,直至互斥量被解锁
函数pthread_mutex_unlock()将解锁之前已遭调用线程锁定的互斥量
2.互斥量的性能
通常情况下,线程会花费更多的时间去做其他工作,对互斥量的加锁解锁相对要少的多,因此使用互斥量对大部分程序来说性能并无显著的影响
3.互斥量的死锁
当一个线程需要同时访问多个共享资源时,没个资源由不同的互斥索管理。当超过一个线程加锁同一组互斥量时,就有可能发生死锁。如下图所示
线程A
1.pthread_mutex_lock(mutex1);
2.pthread_mutex_lock(mutex2);
线程2
1.pthread_mutex_lock(mutex2);
2.pthread_mutex_lock(mutex1);
每个线程都成功的锁住一个互斥量,接着试图对以为另一线程锁定的互斥量加锁,就会一直等下去
要避免此类死锁问题,最简单的就是定义互斥量的层级关系
⑵ linux 线程里面创建线程吗
1、windows里的进程/线程是继承自OS/2的。在windows里,"进程"是指一个程序,而"线程"是一个"进程"里的一个执行"线索"。从核心上讲,windows的多进程与Linux并无多大的区别,在windows里的线程才相当于Linux的进程,是一个实际正在执行的代码。但是,windows里同一个进程里各个线程之间是共享数据段的。这才是与Linux的进程最大的不同。2、在windows下,使用CreateThread函数创建线程,与Linux下创建进程同,windows线程不是从创建处开始运行的,而是由CreateThread指定一个函数,线程就从那个函数处开始运行。此程序同前面的UNIX程序一样,由两个线程各打印1000条信息。threadID是子线程的线程号,另外,全局变量g是子线程与父线程共享的,这就是与Linux最大的不同之处。大家可以看出,windows的进程/线程要比Linux复杂,在Linux要实现类似windows的线程并不难,只要fork以后,让子进程调用ThreadProc函数,并且为全局变量开设共享数据区就行了,但在windows下就无法实现类似fork的功能了。所以现在windows下的C语言编译器所提供的库函数虽然已经能兼容大多数Linux/UNIX的库函数,但却仍无法实现fork。3、对于多任务系统,共享数据区是必要的,但也是一个容易引起混乱的问题,windows下,一个程序员很容易忘记线程之间的数据是共享的这一情况,一个线程修改过一个变量后,另一个线程却又修改了它,结果引起程序出问题。但在Linux下,由于变量本来并不共享,而由程序员来显式地指定要共享的数据,使程序变得更清晰与安全。
⑶ linux下多进程或者多线程编程的问题。新手,望指教!
你好,多进程抄或多线程,都不会阻袭塞当前语句代码。为了您的理解,我就大胆举下面两个例子:
多进程:你可以看成是本来是一条路的,现在从中间拆成两条,然后每一条路都有属于自己这条路的代码在运行。
多线程:你可以看成是一条路,然后分出车道,比如左车道和右车道甚至是停车道,然后每条车道都单独通车,其他车道的不能对这条车道进行干扰。
所以,把一条路从中间拆成两条,成本是很高的。但是把一条路分车道,成本就不是很高了。
对于您提出的main函数的疑问,当main函数最后执行完毕,程序退出后,所有的进程包括线程,都会被关闭的,哪怕你的程序中没有关闭,操作系统也会帮你关闭的,现在的操作系统都非常的完善了。当然,也存在有线程或进程不被释放的特殊情况,最好在编程中要记得释放。