zoukankan      html  css  js  c++  java
  • 线程笔记

    学习笔记(三)之线程:

    进程创建,进程的调度较为消耗硬件资源,进程切换时会涉及到多个硬件资源的切换


    线程本质是带有时间片的函数(模块化代码,多个函数相对独立)


    线程共享资源:
    共享进程空间0~3G空间
    PID

    线程独立的资源:
    线程的栈区独立
    PC指针
    线程errno独立
    线程编号相互独立

    注:不能返回线程空间内的地址

    安装线程库:
    sudo apt-get install manpages-posix-dev
    sudo apt-get install manpages-posix

    线程编程:
    注:
    1.添加#include <pthread.h>
    2.编译时链接线程库 -lpthread
    3.线程中慎用exit函数

    线程创建:本质是线程调用
    pthread_create
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
    参数:1.pthread_create成功执行时可以获取线程编号 准备pthread_t 变量 取地址放入;2.线程属性设置 填NULL表示默认属性
    3.被调用的线程函数的入口地址 void * 线程名(void *);4.用于给第三个参数传参 不需要填NULL
    功能:线程调用函数
    返回值:成功返回0,失败返回错误号,并设置errno号

    线程阻塞函数 类似进程中的waitpid(pid)
    pthread_join
    int pthread_join(pthread_t thread, void **retval);
    功能:阻塞等待指定线程退出
    参数:1.线程号 2.接收pthread_exit返回的信息 定义一个void* p &p放入,不关心填NULL
    返回值:成功返货0,失败返回errno号

    线程退出 类似进程中的exit
    pthread_exit
    void pthread_exit(void *retval);
    功能:结束调用的线程,返回的一个地址(用于记录信息的首地址,不使用填NULL)

    线程取消
    pthread_cancel
    int pthread_cancel(pthread_t thread);
    功能:将指定线程退出

     1 #include <stdio.h>
     2 #include <pthread.h>
     3 #include <stdlib.h>
     4 pthread_t tid1,tid2;
     5 int i = 0;
     6 int a,b;
     7 
     8 
     9 void *fun_a(void *arg)
    10 {
    11     while(1)
    12     {
    13         i++;
    14         a = i;
    15         b = a;
    16     }
    17     pthread_exit(NULL);
    18 }
    19 
    20 void *fun_b(void *arg)
    21 {
    22     while(1)
    23     {
    24         if(a != b)
    25         {
    26             printf("i:%d a:%d b:%d\n",i,a,b);
    27         }
    28     }
    29     pthread_exit(NULL);
    30 }
    31 
    32 int main(int argc, const char *argv[])
    33 {
    34     int ret = 0;
    35     ret = pthread_create(&tid1,NULL,fun_a,NULL);
    36     if(ret != 0)
    37     {
    38         fprintf(stderr,"fail to create pthread1:%d\n",ret);
    39         exit(1);
    40     }
    41     pthread_create(&tid2,NULL,fun_b,NULL);
    42 
    43 
    44     pthread_join(tid1,NULL);
    45     pthread_join(tid2,NULL);
    46 
    47     return 0;
    48 }
    pthread1
     1 #include <stdio.h>
     2 #include <pthread.h>
     3 
     4 pthread_t tid1,tid2;
     5 
     6 //线程A:
     7 void *fun1(void * arg)
     8 {
     9     if(arg != NULL)
    10     {
    11         printf("pthread1_arg:%s\n",(char *)arg);
    12     }
    13     printf("i'm pthread_1!\n");
    14     pthread_exit("hehehe");
    15 }
    16 
    17 
    18 //线程B:
    19 void *fun2(void * arg)
    20 { 
    21     if(arg != NULL)
    22     {
    23         printf("pthread2_arg:%s\n",(char *)arg);
    24     }
    25     printf("i'm pthread_2!\n");
    26     pthread_exit("heiheihei");
    27 }
    28 
    29 
    30 
    31 int main(int argc, const char *argv[])
    32 {
    33      
    34     char *s1 = "zhangyaqi meimeimei";
    35     char *s2 = "jiangtiti meimeimei";
    36     //线程调用
    37     pthread_create(&tid1,NULL,fun1,s1);
    38     pthread_create(&tid2,NULL,fun2,s2);
    39 
    40     char *ret1 = NULL;
    41     char *ret2 = NULL;
    42 
    43     //阻塞主线程等待所有子线程退出
    44     pthread_join(tid1,(void **)&ret1);
    45     pthread_join(tid2,(void **)&ret2);
    46 
    47     printf("pthread1_exit:%s\n",ret1);
    48     printf("pthread2_exit:%s\n",ret2);
    49 
    50 
    51     return 0;
    52 }
    pthread2
     1 #include <stdio.h>
     2 #include <pthread.h>
     3 #include <unistd.h>
     4 
     5 pthread_t tid1,tid2,tid3;
     6 
     7 //线程A
     8 void *fun_a(void *arg)
     9 {
    10     while(1)
    11     {
    12         printf("i'm pthread_a!\n");
    13         sleep(1);
    14     }
    15     pthread_exit(NULL);
    16 }
    17 //线程B
    18 void *fun_b(void *arg)
    19 {
    20     while(1)
    21     {
    22         printf("i'm pthread_b!\n");
    23         sleep(1);
    24     }
    25     pthread_exit(NULL);
    26 }
    27 //线程C
    28 void *fun_c(void *arg)
    29 {
    30     sleep(10);
    31     pthread_cancel(tid1);
    32     pthread_cancel(tid2);
    33 
    34     pthread_exit(NULL);
    35 }
    36 
    37 int main(int argc, const char *argv[])
    38 {
    39     pthread_create(&tid1,NULL,fun_a,NULL);
    40     pthread_create(&tid2,NULL,fun_b,NULL);
    41     pthread_create(&tid3,NULL,fun_c,NULL);
    42 
    43     pthread_join(tid1,NULL);
    44     pthread_join(tid2,NULL);
    45     pthread_join(tid3,NULL);
    46 
    47 
    48 
    49     return 0;
    50 }
    线程取消

    线程同步和互斥:
    同步:本身也是一种特殊的互斥
    互斥:

    1.全局变量:
    做同步没有问题,互斥时可能会出现问题(最好不要用全局变量做互斥)

     1 #include <stdio.h>
     2 #include <pthread.h>
     3 
     4 pthread_t tida,tidb,tidc;
     5 int leda,ledb,ledc;
     6 
     7 void *pthread_a(void *arg)
     8 {
     9     while(1)
    10     {
    11         if(leda == 1)
    12         {
    13             leda--;
    14             printf("i'm pthread_a!\n");
    15             ledb++;
    16         }
    17     }
    18     pthread_exit(NULL);
    19 }
    20 
    21 void *pthread_b(void *arg)
    22 {
    23     while(1)
    24     {
    25         if(ledb == 1)
    26         {
    27             ledb--;
    28             printf("i'm pthread_b!\n");
    29             ledc++;
    30         }
    31     }
    32     pthread_exit(NULL);
    33 }
    34 
    35 void *pthread_c(void *arg)
    36 {
    37     while(1)
    38     {
    39         if(ledc == 1)
    40         {
    41             ledc--;
    42             printf("i'm pthread_c!\n");
    43             leda++;
    44         }
    45     }
    46     pthread_exit(NULL);
    47 }
    48 
    49 
    50 
    51 int main(int argc, const char *argv[])
    52 {
    53     //初始化灯
    54     leda = 1;
    55     ledb = 0;
    56     ledc = 0;
    57 
    58     pthread_create(&tida,NULL,pthread_a,NULL);    
    59     pthread_create(&tidb,NULL,pthread_b,NULL);    
    60     pthread_create(&tidc,NULL,pthread_c,NULL);    
    61 
    62     pthread_join(tida,NULL);
    63     pthread_join(tidb,NULL);
    64     pthread_join(tidc,NULL);
    65 
    66     return 0;
    67 }
    全局变量作同步
     1 #include <stdio.h>
     2 #include <pthread.h>
     3 #include <stdlib.h>
     4 pthread_t tid1,tid2;
     5 volatile int flag;
     6 
     7 
     8 void *fun_a(void *arg)
     9 {
    10     while(1)
    11     {
    12         if(flag == 1)
    13         {
    14             flag--;
    15             printf("i'm pthread_a!\n");
    16             printf("aaaaaaaaaaaaaa\n");
    17             flag++;    
    18         }
    19     }
    20     pthread_exit(NULL);
    21 }
    22 
    23 void *fun_b(void *arg)
    24 {
    25     while(1)
    26     {
    27         if(flag == 1)
    28         {
    29             flag--;
    30             printf("i'm pthread_b!\n");
    31             printf("bbbbbbbbbbbbbb\n");
    32             flag++;
    33         }
    34     }
    35     pthread_exit(NULL);
    36 }
    37 
    38 int main(int argc, const char *argv[])
    39 {
    40     flag = 1;
    41     int ret = 0;
    42     ret = pthread_create(&tid1,NULL,fun_a,NULL);
    43     if(ret != 0)
    44     {
    45         fprintf(stderr,"fail to create pthread1:%d\n",ret);
    46         exit(1);
    47     }
    48     pthread_create(&tid2,NULL,fun_b,NULL);
    49 
    50 
    51     pthread_join(tid1,NULL);
    52     pthread_join(tid2,NULL);
    53 
    54     return 0;
    55 }
    全局变量作互斥

    2.信号量
    sem_init 信号量初始化
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    参数:1.sem_init成功执行时获取对应的信号量编号;  2.决定该信号量用于线程还是进程 填0表示用于线程;3.信号量的初始值
    功能:创建信号量,并设置初始值
    返回值:成功返回0,失败返回-1,并设置errno号

    sem_wait p操作
    int sem_wait(sem_t *sem);
    参数:1.信号量地址
    功能:对指定信号量执行-1操作,如果信号量值为0,则阻塞等待信号量值>0
    返回值:成功返回0,失败返回-1,并设置errno号

    sem_post v操作
    int sem_post(sem_t *sem);
    参数:1.信号量地址
    功能:对指定信号量进行+1操作
    返回值:成功返回0,失败返回-1,并设置errno号

    sem_destroy
    int sem_destroy(sem_t *sem);
    参数:1.信号量的地址
    功能:销毁指定信号量
    返回值:成功返回0,失败返回-1,并设置errno号

     1 #include <stdio.h>
     2 #include <semaphore.h>
     3 #include <pthread.h>
     4 
     5 sem_t sem1,sem2,sem3;
     6 pthread_t tid1,tid2,tid3;
     7 
     8 void *pthread_a(void *arg)
     9 {
    10     while(1)
    11     {
    12         sem_wait(&sem1);
    13         printf("i'm pthread_a!\n");
    14         sem_post(&sem2);
    15     }
    16     pthread_exit(NULL);
    17 }
    18 
    19 void *pthread_b(void *arg)
    20 {
    21     while(1)
    22     {
    23         sem_wait(&sem2);
    24         printf("i'm pthread_b!\n");
    25         sem_post(&sem3);
    26     }
    27     pthread_exit(NULL);
    28 }
    29 
    30 void *pthread_c(void *arg)
    31 {
    32     while(1)
    33     {
    34         sem_wait(&sem3);
    35         printf("i'm pthread_c!\n");
    36         sem_post(&sem1);
    37     }
    38     pthread_exit(NULL);
    39 }
    40 
    41 int main(int argc, const char *argv[])
    42 {
    43     //初始化
    44     sem_init(&sem1,0,1);
    45     sem_init(&sem2,0,0);
    46     sem_init(&sem3,0,0);
    47 
    48     //调用线程
    49     pthread_create(&tid1,NULL,pthread_a,NULL);
    50     pthread_create(&tid2,NULL,pthread_b,NULL);
    51     pthread_create(&tid3,NULL,pthread_c,NULL);
    52 
    53 
    54 
    55     //线程阻塞
    56     pthread_join(tid1,NULL);
    57     pthread_join(tid2,NULL);
    58     pthread_join(tid3,NULL);
    59 
    60 
    61     //销毁信号量
    62     sem_destroy(&sem1);
    63     sem_destroy(&sem2);
    64     sem_destroy(&sem3);
    65     return 0;
    66 }
    信号量作同步
     1 #include <stdio.h>
     2 #include <pthread.h>
     3 #include <semaphore.h>
     4 
     5 pthread_t tid1,tid2,tid3;
     6 sem_t sem1; 
     7 
     8 
     9 void *pthread_a(void *arg)
    10 {
    11     while(1)
    12     {
    13         sem_wait(&sem1);//阻塞等待  如果sem>0 则-1
    14         printf("i'm pthread_a!\n");
    15         sem_post(&sem1);//sem +1
    16     }
    17     pthread_exit(NULL);
    18 }
    19 
    20 
    21 void *pthread_b(void *arg)
    22 {
    23     while(1)
    24     {
    25         sem_wait(&sem1);
    26         printf("i'm pthread_b!\n");
    27         sem_post(&sem1);
    28     }
    29     pthread_exit(NULL);
    30 }
    31 
    32 
    33 void *pthread_c(void *arg)
    34 {
    35     while(1)
    36     {
    37         sem_wait(&sem1);
    38         printf("i'm pthread_c!\n");
    39         sem_post(&sem1);
    40     }
    41     pthread_exit(NULL);
    42 }
    43 
    44 
    45 int main(int argc, const char *argv[])
    46 {
    47     
    48     //创建并初始化信号量
    49     sem_init(&sem1,0,1);    
    50 
    51     pthread_create(&tid1,NULL,pthread_a,NULL);
    52     pthread_create(&tid2,NULL,pthread_b,NULL);
    53     pthread_create(&tid3,NULL,pthread_c,NULL);
    54 
    55 
    56     pthread_join(tid1,NULL);
    57     pthread_join(tid2,NULL);
    58     pthread_join(tid3,NULL);
    59 
    60     //销毁信号量
    61     sem_destroy(&sem1);
    62 
    63 
    64     return 0;
    65 }
    信号量作互斥

    3.互斥锁 实现代码块之间的互斥
    pthread_mutex_init 创建锁
    int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
    参数:1.当pthread_mutex_init成功执行后获取锁号 2.锁的属性 填NULL,按默认属性
    返回值:成功返回0,失败返回错误号

    pthread_mutex_lock 上锁
    int pthread_mutex_lock(pthread_mutex_t *mutex);
    参数:1.锁号的地址
    返回值:成功返回0,失败返回错误号

    pthread_mutex_unlock 解锁
    int pthread_mutex_unlock(pthread_mutex_t *mutex);
    参数:1.锁号的地址
    返回值:成功返回0,失败返回错误号

    pthread_mutex_destroy 销毁锁
    int pthread_mutex_destroy(pthread_mutex_t *mutex);
    参数:1.锁号的地址
    返回值:成功返回0,失败返回错误号

     1 #include <stdio.h>
     2 #include <pthread.h>
     3 #include <stdlib.h>
     4 pthread_t tid1,tid2;
     5 int i = 0;
     6 int a,b;
     7 pthread_mutex_t lock;
     8 
     9 void *fun_a(void *arg)
    10 {
    11     while(1)
    12     {
    13         //上锁
    14         pthread_mutex_lock(&lock);
    15         i++;
    16         a = i;
    17         b = a;
    18         //解锁
    19         pthread_mutex_unlock(&lock);
    20     }
    21     pthread_exit(NULL);
    22 }
    23 
    24 void *fun_b(void *arg)
    25 {
    26     while(1)
    27     {
    28         pthread_mutex_lock(&lock);
    29         if(a != b)
    30         {
    31             printf("i:%d a:%d b:%d\n",i,a,b);
    32         }
    33         pthread_mutex_unlock(&lock);
    34     }
    35     pthread_exit(NULL);
    36 }
    37 
    38 int main(int argc, const char *argv[])
    39 {
    40     //创建锁
    41     pthread_mutex_init(&lock,NULL);
    42 
    43     int ret = 0;
    44     ret = pthread_create(&tid1,NULL,fun_a,NULL);
    45     if(ret != 0)
    46     {
    47         fprintf(stderr,"fail to create pthread1:%d\n",ret);
    48         exit(1);
    49     }
    50     pthread_create(&tid2,NULL,fun_b,NULL);
    51 
    52 
    53     pthread_join(tid1,NULL);
    54     pthread_join(tid2,NULL);
    55 
    56     //销毁锁
    57     pthread_mutex_destroy(&lock);
    58     return 0;
    59 }
    互斥锁


    4.条件变量
    pthread_cond_init 条件变量的初始化
    int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
    参数:1.pthread_cond_init成功执行时获取条件变量编号 2.条件变量的属性 填NULL默认属性
    返回值:成功返回0,失败返回错误号

    pthread_cond_signal
    int pthread_cond_signal(pthread_cond_t *cond);

    pthread_cond_broadcast
    int pthread_cond_broadcast(pthread_cond_t *cond);

    pthread_cond_wait 解锁->等待->上锁
    int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
    参数:1.条件变量编号 2.锁号
    返回值:成功返回0,失败返回错误号

    pthread_cond_destroy 销毁信号量
    int pthread_cond_destroy(pthread_cond_t *cond);
    参数:1.条件变量编号的地址
    返回值:成功返回0,失败返回错误号

     1 #include <stdio.h>
     2 #include <pthread.h>
     3 #include <strings.h>
     4 #include <stdlib.h>
     5 
     6 pthread_mutex_t lock;
     7 
     8 pthread_cond_t cond;
     9 
    10 pthread_t tid1,tid2,tid3;
    11 
    12 char buf[128];
    13 
    14 //线程A  
    15 void *fun_a(void *arg)
    16 {
    17     while(1)
    18     {
    19         bzero(buf,sizeof(buf));
    20         printf("(pthread_a)please input something:\n");
    21         fgets(buf,sizeof(buf),stdin);    
    22         //pthread_cond_signal(&cond);
    23         pthread_cond_broadcast(&cond);
    24         sleep(1);
    25     }
    26     pthread_exit(NULL);
    27 }
    28 
    29 //线程B
    30 void *fun_b(void *arg)
    31 {
    32     while(1)
    33     {
    34         pthread_mutex_lock(&lock);
    35 //        printf("i'm pthread_b!\n");
    36 
    37         pthread_cond_wait(&cond,&lock);
    38         printf("pthread_b buf:%s\n",buf);
    39         if(strncmp(buf,"quit",4) == 0)
    40         {
    41             exit(0);
    42         }
    43 
    44         pthread_mutex_unlock(&lock);
    45     }
    46     pthread_exit(NULL);
    47 }
    48 
    49 
    50 //线程C
    51 void *fun_c(void *arg)
    52 {
    53     while(1)
    54     {
    55         pthread_mutex_lock(&lock);
    56 //        printf("i'm pthread_c!\n");
    57 
    58         pthread_cond_wait(&cond,&lock);
    59         printf("pthread_c buf:%s\n",buf);
    60         if(strncmp(buf,"quit",4) == 0)
    61         {
    62             exit(0);
    63         }
    64 
    65         pthread_mutex_unlock(&lock);
    66     }
    67     pthread_exit(NULL);
    68 }
    69 
    70 int main(int argc, const char *argv[])
    71 {
    72     //创建锁
    73     pthread_mutex_init(&lock,NULL);
    74     
    75     //创建条件变量
    76     pthread_cond_init(&cond,NULL);
    77 
    78     //线程调用
    79     pthread_create(&tid1,NULL,fun_a,NULL);
    80     pthread_create(&tid2,NULL,fun_b,NULL);
    81     pthread_create(&tid3,NULL,fun_c,NULL);
    82 
    83     //线程阻塞
    84     pthread_join(tid1,NULL);
    85     pthread_join(tid2,NULL);
    86     pthread_join(tid3,NULL);
    87 
    88     //回收锁
    89     pthread_mutex_destroy(&lock);
    90 
    91     //回收条件变量
    92     pthread_cond_destroy(&cond);
    93 
    94     return 0;
    95 }
    条件变量
  • 相关阅读:
    LayoutInflater作用及使用
    android中共享全局数据的方法
    http-关于application/x-www-form-urlencoded等字符编码的解释说明
    如何使用V7包中ActionBar(Eclipse版)
    Android Studio如何集成Genymotion
    Andriod Studio科普篇——4.关于编译的常见问题
    Gradle Android最新自动化编译脚本教程
    gradle 2.1构建android出现错误的解决方案
    Eclipse搭建Gradle环境
    eclipse下gradle配置
  • 原文地址:https://www.cnblogs.com/hslixiqian/p/9559422.html
Copyright © 2011-2022 走看看