linux--线程(6)

来源:互联网 发布:批量裁剪图片软件 编辑:程序博客网 时间:2024/06/08 17:53

进程和线程

  • 概念:在Linux中,线程一般被认为是“轻量级的进程”,进程是一个应用程序独立运行单位,而线程不能独立存在,必须由在一个进程创建.
  • 线程相对进程的优点:
    内存数据共享(1.进程需要独立占用各个段运行,线程可以多个同时在一个进程运行,共享同一内存;2.数据通用,效率高)
    提高响应速度
    cpu系统更有效,因为线程会运行在不同cpu
    改善了程序结构,因为一个进程分化为多个线程,单独线程可管理

实现基本函数

  • 基本编程
    常用线程函数
    pthread_attr_init 初始化线程属性 (要在create前初始化)
    pthread_create 创建一个线程
    pthead_exit 线程自行退出(exit(0)函数时退出进程)
    pthread_join 其它线程等待某一个线程退出(释放相关内存资源)
    //线程结束后不能自动释放内存,所以要用函数释放
    pthread_detach 使得子线程本身自己有自我回收内存资源的能力
    pthread_cancel 当前线程将杀死其他的线程
    pthread_self 获得当前线程的标志

  • 具体函数

    • 线程创建
      函数原型是:
      int pthread_create(pthread_t* thread,
      pthread_attr_t* attr,
      void (*start_routine)(void),
      void * arg);

      第一个参数是pthread_t类型的指针,这个指针指向用来存放当线程创建成功后的所创建的线程的标志
      第二个参数表明被创建的线程可以拥有的属性
      第三个参数是一函数指针,此函数指针指向线程的实现函数
      第四个参数arg是void *类型的,此参数指向实际线程处理函数执行的时候所需要的参数

    • 线程退出
      线程的退出有两种方式:
      线程函数运行结束,比如到函数结尾或用return退出.线程自然结束.这是最常用的方式
      可以显式的调用pthread_exit()结束线程执行
      函数原型是:
      void pthread_exit(void*retval);
      参数是指向线程的返回值
      线程的退出不能简单使用exit()函数,因为一旦使用了exit()函数,实际上是整个进程的退出,会导致其他线程也随着进程的消亡而消亡
    • 等待线程退出
      线程创建完毕后,创建线程的线程,就可以使用pthread_join() 函数等待被创建的线程的结束。pthread_join()函数会挂起创建线程的线程的执行,直到等待到想要等待的子线程
      函数原型:
      int pthread_join(pthread_t th, void **thread_return);
      第一个参数th是需要等待的线程的标志
      如果thread_return不为空,那么thread_return指向th返回的值
      调用pthread_join()函数的目的是释放相关内存资源
    • 线程分离
      使得子线程本身自己有自我回收内存资源的能力
      函数原型:
      int pthread_detach(pthread_t th);
      这个函数的目的是让线程th可以处于分离(detached)状态
      处于分离状态的线程有能力在自己结束执行的时候回收相关的内存资源
      当前线程标志
      使用pthread_self()函数可以获得当前线程的标志
      函数原型:
      pthread_t pthread_self(void);
    • 线程的撤消
      一个线程可以通过向另个线程发送“请求”来结束另一个线程的执行。pthread_cancel()函数可以完成这个功能。
      函数原型:
      pthread_cancel(pthread_t thread)
      当前线程将杀死线程ID为thread的线程
      pthread_exit()是当前线程自已退出,而pthread_cancel是其它线程杀死别的线程

实现代码

//有bug#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>void *Helloworld(void *arg){    int i=1;    while(1)    {        printf("==Hello==");        if(i==3){            //线程退出1            pthread_exit(NULL);        }        //退出整个**进程**        exit(0);    }    //线程退出2    return NULL;}int main(int argc, char *argv){    int i;    pthread_t tid;    //线程创建    if(pthread_create(&tid, NULL, Helloworld, NULL) != 0){        printf("==fail ==");        return -1;    }    printf("==main==");    for(i=1; i<5; i++)    {        printf("!==main==");    }    return 0;
  • 步骤
    1.创建.c文件#touch m_pthread.c
    2.编辑#vi m_pthread.c
    3.链接#gcc -o fred m_pthread.c -lpthread
    4.执行#./fred

  • pthread线程库的使用
    glib库内置了线程库.
    在源码中使用头文件 pthread.h
    用gcc链接时加上 –lpthread 选项,链接线程库

线程互斥(Mutex)

同步和互斥区别:
同步:一个执行,另一个相应执行(一起执行)
互斥:一个执行,另一个等待它执行完成才可以执行(单个单个执行)

  • mutex作用:用来保护并发读写操作中的共享的数据结构,实际上用mutex可以用来实现临界代码区,本身状态只有锁定和非锁定状态
  • 特性:
    原子性:一个线程进行mutex操作,其他不能对同一个mutex操作
    单一性:拥有mutex的一个线程除非释放它,否则其他线程不能拥有
    非忙等待:等待解锁才可使用此mutex

  • mutex基本函数
    死锁:停在某个地方不运行
    int pthread_mutex_init
    int pthread_mutex_lock
    int pthread_mutex_trylock
    int pthread_mutex_unlock
    int pthread_mutex_destroy

线程的同步

条件变量是线程的同步设备
- 基本函数
pthread_cond_t cond= PTHREAD_COND_INITIALIZER;
int pthread_cond_init 初始化条件变量
int pthread_cond_signal 启动等待cond指向的条件变量的一个线程
int pthread_cond_broadcast 启动所有的等待条件变量的线程
int pthread_cond_wait 原子性地解锁其第二个参数指向的mutex,然后等待条件变量条件的满足
int pthread_cond_timedwait 在规定的时间内等待条件的满足
int pthread_cond_wait 无限等待
int pthread_cond_destroy 释放条件变量所占的资源

信号量

POSIX 信号量在多线程编程中可以起到同步或互斥的作用。用POSIX 信号量可以实现传统操作系统P(通过)、V(释放)操作

对POSIX信号量的操作函数有:
int sem_init 初始化信号量
int sem_wait 阻塞当前线程的执行
int sem_trywait
int sem_post sem指向的信号量计数加1,相当于V 操作
int sem_getvalue 得到当前信号量的值
int sem_destroy 释放信号量资源

0 0
原创粉丝点击