总结:
1, 在Linux下并不区分线程与进程,也就是说系统并不认为自己有线程这个东西,创建线程的函数pthread_create(pthread_t * p,NULL, (void*)func(void*arg) ,NULL); 是调用了POSIX的库函数,不是系统调用。也就是利用posix库函数模拟出来了线程。
2, 线程ID有两种:
1> 放在线程PCB中的pid,供系统调用时使用(轻量级进程) 2> 在创建线程时的返回型参数,pthread_t id,供编程时使用, 如线程等待函数,pthread_join(pthread_t id , NULL); 该函数用于等待进程并回收进程资源。3,证明:同一进程内的多个线程公用同一块虚拟地址空间 答:
创建多个线程,去修改同一全局变量,最终每个进程得到的变量都一样。 使用fork创建子进程,父子进程同时修改全局变量,最终得的值不一样,这是因为子进程独自拥有一份虚拟地址空 间,在变量发生改变时,通过改变页表,完成写时拷贝。4,为啥要有互斥
1> 多进程,多线程执行的先后顺序不同,切换的时机也不确定。
2> 多进程,多线程访问变量的动作不是原子的。
5,如何避免死锁 1> 短:临界区代码简短明了。
2> 平:临界区代码逻辑清晰,无复杂的函数调用。 3> 快:临界区代码执行速度快。typedef struct
{
int detachstate; 线程的分离状态 int schedpolicy; 线程调度策略 structsched_param schedparam; 线程的调度参数 int inheritsched; 线程的继承性 int scope; 线程的作用域 size_t guardsize; 线程栈末尾的警戒缓冲区大小 int stackaddr_set; void* stackaddr; 线程栈的位置 size_t stacksize; 线程栈的大小}pthread_attr_t;
1、线程的分离状态
线程的分离状态决定一个线程以什么样的方式来终止自己。在默认情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动。
2、线程的继承性
继承性决定调度的参数是从创建的进程中继承还是使用在schedpolicy和schedparam属性中显式设置的调度信息。Pthreads不为inheritsched指定默认值,因此如果你关心线程的调度策略和参数,必须先设置该属性。 继承性的可能值是PTHREAD_INHERIT_SCHED(表示新现成将继承创建线程的调度策略和参数)和PTHREAD_EXPLICIT_SCHED(表示使用在schedpolicy和schedparam属性中显式设置的调度策略和参数)。 如果你需要显式的设置一个线程的调度策略或参数,那么你必须在设置之前将inheritsched属性设置为PTHREAD_EXPLICIT_SCHED.1,为啥要有互斥
多进程,多线程执行的先后顺序不同,切换的时机也不确定。
多进程,多线程访问变量的动作不是原子的。
例如:i++ cpu完成时会有三步操作,任意切换会导致出错
2,为啥要有同步:
多进程,多线程执行的先后顺序不同,切换的时机也不确定。 想要不同的线程为我们完成具有顺序的部分任务,就必须是使其具有顺序。给临界资源加锁,保证原子性
#include<stdio.h> 2 #include<pthread.h> 3 #include<unistd.h> 4 int count =0; 5 pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; 6 void * thread_run(void*arg) 7 { 8 int i=0; 9 while(i<50000000) 10 { 11 pthread_mutex_lock(&lock); 12 count++; 13 14 pthread_mutex_unlock(&lock); 15 i++; 16 } 17 18 19 20 21 } 22 int main () 23 { 24 pthread_t tid1,tid2; 25 pthread_create(&tid1,NULL,thread_run,NULL); 26 pthread_create(&tid2,NULL,thread_run,NULL); 27 pthread_join(tid1,NULL); 28 pthread_join(tid2,NULL); 29 printf(" res count is %d\n",count); 30 return 0; 31 }