linux 多线程

1,线程与进程的区别
(1)进程
是一个正在执行的程序,是系统资源分配的实体
每个进程都有自己的PCB
(2)线程
进程和线程创建 内核使用的都是clone函数;
所有的缺省的线程平分栈的大小
线程栈与线程栈之间有一款线程安全区。
进程是资源竞争的基本单位
线程是程序执行的最小单位
线程共享进程数据,代码段,堆,但是有自己拥有的东西:线程ID>一组寄存器>栈>errno>信号屏蔽字>调度优先级
线程中最好不要处理信号;

操作系统引入线程的目的:
进程在运行时,由于进程调度算法的原因,不可避免的会出现进程之间的切换,而进程之间的切换时非常耗时的,为了解决这一问题,引入了多线程的解决方法;
线程,又称轻进程,在一个进程中创建多个线程去处理多个问题,线程在切换时不会切换进程,从而节省了时间。
不同进程的线程之间切换会引起进程的切换,同一进程中的线程切换不会引起进程的切换。进程的切换一定会引起线程的切换。

2,线程操作
(1)线程的创建
int pthread_create(pthread_t thread, const pthread_attr_t *attr, void (start_routine) (void ), void *arg);
pthread_create(线程ID,线程属性,线程需要执行的函数的地址,传给线程启动函数的参数)
(2)等待线程
int pthread_join(pthread_t thread,void **arg);
(3)结束线程
1,return
2,pthread_exit;(只会退出一个线程,不能退出进程,进程中的其他线程依然在执行,最后一个线程例外)
3,pthread_cancel;(关闭一个其他的线程)//遇到一个cancel点才会结束到一个线程
pthread_testcancel();(设置cancel点)
(4)获取线程id
pthread_t pthread_self();
(5)线程分离
int pthread_detach(pthread_t tid);
(6)初始化线程
int pthread_attr_init(pthread_attr_t* attr);

int ptnread_attr_destory(pthread_attr_t* attr);

               Detach state        = PTHREAD_CREATE_JOINABLE  //线程分离属性
               Scope               = PTHREAD_SCOPE_SYSTEM
               Inherit scheduler   = PTHREAD_INHERIT_SCHED
               Scheduling policy   = SCHED_OTHER   
               Scheduling priority = 0
               Guard size          = 4096 bytes  //线程之间的安全距离
               Stack address       = 0x40196000  //线程栈初始地址
               Stack size          = 0x201000 bytes  //线程栈大小

(1)自己定义线程栈
            int pthread_attr_setstack(pthread_attr_ t* attr, void* attraddr,size_t stacksize);
(2)设置线程栈的大小
            int pthread_attr_setstacksize(pthread_attr_t * attr,size_t stacksize);

下面创建一个线程实例来加深理解

#include <stdio.h>                                                                                    #include <stdlib.h>
   #include <pthread.h>
   #include <string.h>
   void *route1()
   {
       while(1)
           printf("hello\n");
   }
 void *route2()
 {
      while(1)
          printf("hello router2\n");
  }
 void *route3()
  {
      while(1)
          printf("hello route3\n");
  }
 int main() {
      pthread_t tid1;
      pthread_t tid2;
      pthread_t tid3;
      int ret1 =  pthread_create(&tid1,NULL,route1,NULL);
      if(ret1!=0)
          printf("pthread_create:%s\n",strerror(ret1));
      int ret2 = pthread_create(&tid2,NULL,route2,NULL);
      if(ret2!=0)
         printf("ptreath_create2:%s\n",strerror(ret2));
          int ret3 = pthread_create(&tid3,NULL,route3,NULL);
      if(ret3!=0)
          printf("pthread_create3:%s\n",strerror(ret3));
      //1当进程退出,进程中所有线程就退出
      //解决办法:pthread_join等待线程
      //2创建好线程以后,每个线程都从参与时间片的分配
      //3当线程处理函数结束之后,线程就结束
      // pthread_join(tid,NULL);
     while(1)
          printf("hello.man\n");
  }

线程的同步与互斥
1,线程分离
pthread_detach(pthread_t thread);

//互斥锁:同步线程对共享数据的访问
           建议锁,不是强制的
        1,定义全局变量  pthread_mutex_t metux; 
        2,初始化  pthread_mutex_init(&metux,NULL);
        3, 上锁:pthread_mutex_lock(&mutex);                      mutex ==1 将mutex置0?返回
                                                                                            mutex==0? 等待
        4,解锁:pthread_mutex_unlock(&mutex);         mutex=1,返回

        5,销毁:pthread_mutex_destory(&mutex);

    void pthread_cleanup_push(void(*routine)(void*),void *arg);  回调函数遇到//1pthread_exit()        才会触发
                                                                                                                                //2,pthread_cancel()
                                                                                                                                //3,pop(1)

    void pthread_cleanup_pop(int execute);

//自旋锁
1,pthread_spin_t spin
2,pthrad_t_spin_init
3,pthrad_t_spin_lock
4,pthrad_t_spin_unlock
5,pthrad_t_spin_destory

//读写锁:读读共享,读写互斥,写的优先级高

    1,pthread_rwlock_t rwlock;
    2,pthread_rwlock_init(&rwlock,NULL)
    3,pthread_rwlock_rdlock(&rwlock);
    4,pthread_rwlock_wrlock(&rwlock);
    5,pthread_rwlock_unlock(&rwlock);
    6,pthread_rwlock_destory(&rwlock);

//条件变量   同步共享数据的值
    1,pthread_cond_t cond
    2,pthread_cond_init(&cond,NULL)
    3,pthread_cond_wait(&cond,&mutex)  //阻塞,将mutex置为1
                                                                     //返回,将mutex恢复为原样
    4,pthread_cond_signal(&cond)
    5,pthread_cond_destory(&cond)

    使用规范:
        pthread_mutex_lock(&mutex);
            while(条件不满足)
                    pthread_cond_wait(&cond,&mutex)
        pthread_mutex_unlock(&mutex);
        pthread_mutex_lock(&mutex); 
        pthread_cond_signal(&cond); //如果没有线程等在wait,singal就丢失
        pthread_mutex_unlock(&mutex);

POSIX信号量:
初始化信号量
int sem_init(sem_t*sem,
int pshare,//表示本进程内多个线程的同步互斥
unsigned int value);//设置初值
销毁信号量
int sem_destory(sem_t* sem);

      p操作
        int sem_wait(sem_t* sem);
      v操作
        int sem_post(sem_t* sem);

猜你喜欢

转载自blog.csdn.net/liuxiaokai_liu/article/details/80471533