关于线程

什么是线程?其实线程就是一个轻量级的进程,在Linux系统里面,一个进程可以包含多个异步执行的线程,就是一个进程在宏观上表现为处理多个事件。
Linux的线程实现是在核外进行的,核内提供的是创建进程的接口do_fork()。内核提供了两个系统调用__clone()和fork (),最终都用不同的参数调用do_fork()核内API。当然,要想实现线程,没有核心对多进程(其实是轻量级进程)共享数据段的支持是不行的,因此,do_fork()提供了很多参数,包括CLONE_VM(共享内存空间)、CLONE_FS(共享文件系统信息)、CLONE_FILES(共享文件描述符表)、CLONE_SIGHAND(共享信号句柄表)和CLONE_PID(共享进程ID,仅对核内进程,即0号进程有效)。当使用fork系统调用时,内核调用do_fork()不使用任何共享属性,进程拥有独立的运行环境,而使用pthread_create()来创建线程时,则最终设置了所有这些属性来调用__clone(),而这些参数又全部传给核内的do_fork(),从而创建的线程拥有共享的运行环境,只有栈是独立的,由 __clone()传入。

Linux线程在核内是以轻量级进程的形式存在的,拥有独立的进程表项,而所有的创建、同步、删除等操作都在核外pthread库中进行。pthread 库使用一个管理线程(__pthread_manager(),每个进程独立且唯一)来管理线程的创建和终止,为线程分配线程ID,发送线程相关的信号(比如Cancel),而主线程(pthread_create())的调用者则通过管道将请求信息传给管理线程。

为什么要使用多线程?
现在假设有一个进程是处理实时输入的数据,并进行一系列的处理然后产生输出数据,若没有采用多线程的话,只能是同步的执行:数据输入,处理,输出,在进行第二个数据的输入。。。。,这样循环同步处理,如果采用多线程,就可以采用多个线程进行时间的处理,如:一个线程处理数据的输入部分,而另一个线程处理数据的输出部分程序,这样 上面的问题就避免了;
进程和线程的区别?
        不同的进程在不同的地址空间进行执行,然而同一个进程的多个线程共享相同的地址空间(这样线程是很节省资源的);
        进程的执行一般是相当独立的,进程间的同步性有内核控制,而同一个进程的不同线程间一般是存在数据交换的(这也是多线程的产生的原因之一),这一机制是有进程控制的;
        进程的切换要不线程花费更多的时间;
        线程间通讯更加的简单,途径更多(因为他们共享内存空间,代码段等);
用户空间的线程和内核空间线程
线程可以同时存在于用户空间和内核空间;
在用户空间,线程的创建,控制,和撤销都是通过线程库进行的(也就加#include <pthread.h>),用户空间线程对内核是透明的,用户空间的线程调度开销比较小,缺点是不能预调度,而且,在进行一个多任务处理的几个用户线程,一旦有一个碰亏,那么内核结束此进程;
………………………………………………
gcc –o xxxxx –lpthread xxxxx.c//手动链接线程库
……………………………………………
在内核空间,线程的创建,控制,和撤销都是通过内核进行的,而且,内核空间的多个线程在进行多任务处理时,是可以进行预调度的,而且,一个线程的阻塞,不会导致整个进程的阻塞;一般的系统调用就会产生内核线程;
用户空间的线程和内核空间线程存在映射机制;
线程级数据--------TSD
在单进程的任务处理中,变量有局部变量和全局变量,在多线程里,有一种叫做TSD(进程相关数据)的东东,它对于某个线程来说是全局的,对于进程来说是局部的;
进程相关数据的创建,设置,和 删除:
创建:
int pthread_key_create(
pthread_key_t *key,/*分配的键,所有线程共享,但是不同的线程可以为它赋不同的值;*/
void (*destructor) (void *)//销毁函数;
);
。。。。。。。。。。。。。。。。。。。。。。。。
#include <pthread.h>
pthread_key_t key;
int ret;
ret = pthread_key_create(&key, NULL);//默认的处理
ret = pthread_key_create(&key, destructor);
。。。。。。。。。。。。。。。。。。。。。。。
删除:
int pthread_key_delete(pthread_key_t key);
。。。。。。。。。。。。。。。。。。。。。。。
#include <pthread.h>
pthread_key_t key;
int ret;
ret = pthread_key_delete(key);
 
赋值:
int pthread_setspecific(pthread_key_t key, const void *value);
 
获取key值:
 
int pthread_getspecific(pthread_key_t key);
 
1,创建线程
int pthread_create(
pthread_t *tid,//线程标示符的指针
const pthread_attr_t *tattr,//设置线程属性,如果为NULL,就是默认属性;
void*(*start_routine)(void *),/*线程开始运行的函数入口,其实他是一个函数指针,该指针只想一个返回值为指针类型的函数*/
void *arg//运行函数的参数,传递给上面的函数
);
函数成功执行,会返回一个0,其他的任何返回值都是错误的代码;
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
void* a(void* b)
{
int id;
while(1)
printf("x\n");
printf(“id\n”,pthread_self());
return NULL;
}
int main ()
{
pthread_t thread_id;
pthread_create(&thread_id,NULL,a,NULL);
while (1)
printf("c");
printf(“id\n”,pthread_self());//获取线程的线程ID;
return 0;
}
}。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
线程有两种状态
joinable:默认状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符,只有当你调用了pthread_join之后这些资源才会被释放。
unjionable: 线程函数自己返回退出时或pthread_exit时都会释放线程所占用堆栈和线程描述符。通过pthread_detach(thread_id)设置;
2,等待线程终止函数;
int pthread_join(
thread_t tid,//等待要结束线程的ID,该线程的状态必须是jionable;
void **status//存放等待线程结束时返回的值,通常为NULL;
);
当等待的线程已经终止时,那么这个函数就会立即返回。
线程退让函数:
int sched_yield(void);
当一个线程执行此函数时,就会退出执行,然后就会让与其优先级相同或更高的进程执行;
设置线程优先级:
int pthread_setschedparam(
pthread_t tid, 
int policy,//调度策略
const struct sched_param *param/* param是struct sched_param类型的指针,仅包含sched_priority成员,指明该优先级*/
);
调度策略包括:
SCHED_OTHER--------分时调度,线程创建时的默认状态,优先级都是0;
SCHED_RR-----------轮换调度策略;
SCHED_FIFO---------先进先出策略,适用于超级用户线程;
获取线程优先级:
int pthread_getschedparam(
pthread_t tid,
int policy,
struct schedparam *param
)
有时还可向线程发送信号如:pthread_kill(id,signal)://信号的接受者和发送者属于同一个进程;
终止一个线程:
一个线程可以通过三种途径结束:
1)      调用pthread_exit()函数;
2)      根据POSIX 提供的pthread_cancel()函数;
3)      主动返回;
简单总结 仅供参考
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值