• 线程总结


    进程:

    优点:多个进程并发执行,能够参与系统调度,是资源管理和程序执行的最小单位。

    缺点:占用资源(无论哪种通信方式都需要创建第三方),效率低下(每次对数据的访问都需经过第三方),系统开销大(进程退出需要保存,执行需要加载资源)。

    线程:

    优点:多个线程并发执行--à系统调度的最小单位。

    与进程共享资源。

    同一进程中创建的线程共享进程地址空间。

    Linux中使用task_struct来描述一个线程。

    一个进程中的多线程可以共享以下资源:

    可执行的指令

    静态数据

    进程中打开的文件描述符

    信号处理函数

    当前工作目录

    用户ID

    用户组ID

    堆空间要共享可将其指针声明为全局变量,函数中再为其分配空间。

    栈区是私有的,也就是局部变量。

    线程的相关操作:

    线程的创建:

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

    thread:线程id

    attr:线程属性     NULL为默认属性。

    routine:线程执行的函数

    arg:传递给线程执行的参数 

    等待线程退出:

    int pthread_join(pthread_t thread, void **retval);

    Retval:用于捕获线程的退出信息==waitpid()捕获exit的退出编号

    线程退出:

    void pthread_exit(void *retval);

    retval==”pthread is out”;可以填NULL

    取消线程:一个线程通知另一个线程退出;

    int pthread_cancel(pthread_t thread);

    thread:要取消的线程。

    范例:

    #include<pthread.h>

    #include<stdio.h>

    #include<stdlib.h>

    #include<string.h>

    struct messages

    {

    int a;

    int b;

    };

    void *hello(void *s)

    {

    struct messages s1=*(struct messages *)s;

    printf("the sturct messages s__a=%d  ",s1.a);

    printf("the sturct messages s__b=%d  ",s1.b);

    }

    int main()

    {

    struct messages test;

    pthread_t thread_id;

    test.a=33;

    test.b=44;

    pthread_create(&thread_id,NULL,hello,(void *)&test);

    printf("the new thread id is %u  ",thread_id);

    pthread_join(thread_id,NULL);

    }

    char message[32] = "Hello World";

    void *thread_function(void *arg);

    pthread_exit() pthrad_join()范例:

    int main(int argc,  char *argv[])

    {

    pthread_t  a_thread;

        void *thread_result;

    if (pthread_create(&a_thread, NULL, thread_function, (void *)message)  < 0)

               /*使用缺省属性创建线程*/

      {  

           perror("fail to pthread_create");     

           exit(-1);

       }

       printf("waiting for thread to finish ");

       if (pthread_join(a_thread, &thread_result) < 0)  // 等待线程结束

       {

           perror("fail to pthread_join");

           exit(-1);

       }

       printf("MESSAGE is now %s ", message);

       printf("pthread eixt message is  %s ",thread_result);

       return 0;

    }

      void  *thread_function(void *arg)

       {

             printf("thread_function is running, argument is %s ", (char *)arg);

             strcpy(message,  "marked by thread");

             pthread_exit("Thank you for the cpu time");

       }

    Pthread_cancel()范例:

    void *thread_function(void *arg);

    int main()

    {

    int res;

    pthread_t a_thread;

    res =pthread_create(&a_thread,NULL,thread_function,NULL);

    if(res!=0)

    {

    perror("thread failed");

    exit(-1);

    }

    sleep(5);

    printf("cancelling thread.... ");

    res = pthread_cancel(a_thread);

    if(res!=0)

    {

    perror("thread failed");

    exit(-1);

    }

    printf("wainting for thread ");

    res = pthread_join(a_thread,NULL);

    if(res!=0)

    {

    perror("thread join failed");

    exit(-1);

    }

    exit(0);

    }

    void *thread_function (void *arg)

    {

    int i;

    for(i=0;i<9;i++)

    {printf("thread is running(%d)... ",i);

     sleep(1);

    }

    pthread_exit(0);

    }

    线程的执行顺序的控制:

    互斥锁:

    用于操作共享资源:先判断锁的状态,如果已解锁,先上锁,在操作。操作完解锁

    如果已上锁则会阻塞;

    1. 互斥锁初始化:

    int pthread_mutex_destroy(pthread_mutex_t *mutex);  //销毁锁

    int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);//初始化锁

    锁上,阻塞线程:谁上锁,谁解锁。

    int pthread_mutex_lock(pthread_mutex_t *mutex);//先查看锁的状态,如果未解锁,阻塞

    int pthread_mutex_trylock(pthread_mutex_t *mutex);上锁不阻塞。

    int pthread_mutex_unlock(pthread_mutex_t *mutex);//查看锁的状态,为上锁则阻塞。

    互斥锁范例:特别经典(注意锁的走向)

    #include<stdio.h>

    #include<unistd.h>

    #include<stdlib.h>

    #include<pthread.h>

    #include<semaphore.h>

    #include<string.h>

    #define WORK_SIZE 1024

    void * thread_function(void *arg);

    pthread_mutex_t work_mutex;

    char work_area[WORK_SIZE];

    int time_to_exit =0;

    int main(int argc,char *argv[])

    {

    int res;

    pthread_t a_thread;

    void *thread_result;

    res = pthread_mutex_init(&work_mutex,NULL);

    if(res !=0)

    {

    printf("mutex initialization failed ");

    exit(-1);

    }

    res = pthread_create(&a_thread,NULL,thread_function,NULL);

    if(res !=0)

    {

    printf("thread create failed ");

    exit(-1);

    }

    pthread_mutex_lock(&work_mutex);

    printf("input some text,enter 'end' to finish ");

    while(!time_to_exit)

    {

    fgets(work_area,WORK_SIZE,stdin);

    pthread_mutex_unlock(&work_mutex);

    while(1)

    {

    pthread_mutex_lock(&work_mutex);

    if(work_area[0]!='')

    {

    pthread_mutex_unlock(&work_mutex);

    sleep(1);

    }

    else

    break;

    }

    }

    pthread_mutex_unlock(&work_mutex);

    printf("waiting for thread to finish... ");

    res = pthread_join(a_thread,&thread_result);

    if(res !=0)

    {

    printf("thread join failed ");

    exit(-1);

    }

    printf("thread join  ");

    pthread_mutex_destroy(&work_mutex);

    exit(-1);

    }

    void *thread_function(void *arg)

    {

    pthread_mutex_lock(&work_mutex);

    while(strncmp("end",work_area,3)!=0)

    {

    printf("you input %d charactes ",strlen(work_area)-1);

    printf("the characters is %s",work_area);

    work_area[0]='';

    pthread_mutex_unlock(&work_mutex);

    sleep(1);

    pthread_mutex_lock(&work_mutex);

    while(work_area[0]=='')

    {

    pthread_mutex_unlock(&work_mutex);

    sleep(1);

    pthread_mutex_lock(&work_mutex);

    }

    }

    time_to_exit=1;

    work_area[0]='';

    pthread_mutex_unlock(&work_mutex);

    pthread_exit(0);

    }

    条件变量:

    创建条件变量:

    int pthread_cond_destroy(pthread_cond_t *cond);//销毁

    int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);//初始化

    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    条件阻塞:接收到条件变量的信号则退出阻塞状态

    int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,

                  const struct timespec *restrict abstime);

     int pthread_cond_wait(pthread_cond_t *restrict cond,

                  pthread_mutex_t *restrict mutex);

    发送条件变量:

    int pthread_cond_broadcast(pthread_cond_t *cond);//给所有的线程广播信号,让阻塞的线程退出阻塞。

     int pthread_cond_signal(pthread_cond_t *cond);给单个线程发送信号,退出阻塞。

    条件变量必须和互斥锁搭配使用

    #include<pthread.h>

    #include<stdio.h>

    #include<stdlib.h>

    #include<string.h>

    int a,b;

    pthread_mutex_t mutex;

    pthread_cond_t cond;

    void *f1(void *p)

    {

    pthread_mutex_lock(&mutex);

    printf("a = %d,b=%d ",a,b);

    printf("hello ");

    pthread_mutex_unlock(&mutex);

    pthread_cond_signal(&cond);//需要读完了数据才发送信号。

    }

    int main()

    {

    a = 2;

    b = 10;

    pthread_t pthreadid;

    pthread_cond_init(&cond,NULL); 

    pthread_mutex_init(&mutex,NULL);

    pthread_create(&pthreadid,NULL,f1,NULL);

    while(1)

    {

    pthread_mutex_lock(&mutex);

    printf("a = %d,b=%d ",a,b);

    a++;

    b--;

    if(a == b)

    {pthread_cond_wait(&cond,&mutex);//只有锁住了才会有阻塞,wait才能有用

    exit(0);

    }

    pthread_mutex_unlock(&mutex);

    }

    }

  • 相关阅读:
    eclipse快捷键
    go 中 var声明对比
    Post 中 Body 的 ContentType 用 Postman 举例
    MongoDB随笔(二) mongorestore恢复数据库
    MongoDB随笔(零) mongod配置 ...不断完善...会变得很长很长很长……
    MongoDB随笔(一)mac OSX下brew安装MongoDB
    mac OSX的 brew软件包管理器 相当于 centos下的yum
    2021-01-27 解决mac使用brew update更新无反应的问题(切换git地址)
    Ruby中实现module继承
    redmine问题集锦
  • 原文地址:https://www.cnblogs.com/defen/p/5251683.html
Copyright © 2020-2023  润新知