linux——线程

  • Post author:
  • Post category:linux




进程与线程

linux进程可以看成只有一个控制线程,即(一个进程最少有一个线程);有了多个线程之后,进程可以在同一时刻做很多事,每个线程处理独立的任务。

进程是程序运行的一个实例,担当分配系统资源的基本单位,在面向线程设计的系统中,进程不是基本运行单位,进程是线程的容器。

进程有独立的地址空间,一个进程崩溃后不会影响其他进程;线程是一个进程的不同执行路径。线程没有单独的地址空间,有自己的堆栈和局部变量,所以一个线程死掉等于整个进程死掉。多进程的程序比多线程的程序健壮;但是进程消耗资源大。



使用线程的理由

进程有独立的地址空间,线程没有单独的地址空间(同一个进程内的线程共享进程的地址空间)


理由1:线程一种非常节俭的多任务操作方式;

启动一个进程需要给他分配独立的地址空间,建立众多的数据表来维护他的代码段,数据段和堆栈段;这种方式十分昂贵。而运行一个进程中的多个线程,它们使用共同的地址空间,共享大部分数据;启动一个线程所花费的时间远远小于启动一个进程所用的时间。一个进程的开销大概是一个线程的开销的30倍。


理由2:线程间方便的通信机制。对不同进程来说,他们具有独立的数据空间,进行数据的传递只能通过通信的方式,这种方式非常耗时和费力。而同一个进程下的进程共享数据空间,所以一个线程的数据可以为多个线程使用,非常快捷和方便。数据的共享可能也带来一些问题,有的变量不能同时被线程修改,有的子程序声明为static的数据更有可能给多线程程序带来灾难性的打击。


总结:一个进程运行时要分配他的系统资源,维护他的数据段,代码段,堆栈段等等。而线程则共享一个进程的数据段,代码段,堆栈段这些东西;而开辟多个线程的时候,不会开辟内存和cpu,不会浪费内存,是非常节俭的多任务操作方式。



多线程开发及API

多线程开发主要包含三点:

线程,互斥锁,条件;

线程操作又分为线程的创建,退出,等待;

互斥锁则包含:创建,销毁,加锁和解锁;

条件操作有:创建,销毁,触发,广播和等待;

pthread是一个无符号长整型数

1.线程创建:

API:

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号
当pthread成功返回后,tidp为新创建线程的ID,attr参数用于定制不同的线程属性,暂可以设置为NULL,创建默认属性的线程。新创建的线程从start_rtn地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构体中,然后把这个结构的地址作为arg参数传入。

2.线程的获取和比较

获取线程的id号

API:

#include<pthread.h>
pthread_t pthread_self(void);

3.线程的等待

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
pthread_t thread:哪个线程
void **rval:收回线t程的退出状态;NULL代表不收回。

4.线程的退出

#include <pthread.h>
int pthread_exit(void *rval_ptr);

线程的创建,退出,等待;

#include<stdio.h>
#include<pthread.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//pthread_t pthread_self(void);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_exit(void *rval_ptr);

void *func1(void *arg)
{
   static int ret=10;
   printf("t1:%ld thread  is  create\n",(unsigned long)pthread_self());
   printf("t1:pararm is %d\n",*((int *)arg));
   pthread_exit((void*)&ret);//线程退出
}

int main()
{
    int ret;
    int pararm=100;
    int *pret=NULL;
    pthread_t t1;

    ret=pthread_create(&t1,NULL,func1,(void*)&pararm);//创建线程
    if(ret==0){
        printf("main:create t1 succees\n");
    }
    printf("main:%ld",(unsigned long)pthread_self());//获取线程的ID号
   
    pthread_join(t1,(void **)&pret);  //等待线程的退出
    printf("main:t1 quit %d\n",*pret);
    return 0;
}

传入一个结构体

#include<stdio.h>
#include<pthread.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//pthread_t pthread_self(void);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_exit(void *rval_ptr);

struct data
{
    int a;
    char *s;
};


void *func1(void *arg)
{
    static char *x="t1 run out";
    struct data *temp;
    temp=(struct data*)arg;
    printf("t1:%ld pthread is create\n",(unsigned long)pthread_self());
    printf("t1:%d",temp->a);
    printf("t1:%s",temp->s);
    pthread_exit((void*)x);
}

int main()
{
    int ret;
    pthread_t t1;
    char *pret=NULL;
    struct data *p=NULL;
    p=(struct data*)malloc(sizeof(struct data));
    p->a=1;
    p->s="xiancheng";
    
    ret=pthread_create(&t1,NULL,fun1,(void*)&data);
    if(ret==0){
        printf("main:create t1 succees\n");
    }
    
    printf("main:%ld",(unsigned long)pthread_self());

    pthread_join(t1,(void**)&pret);
    printf("main:t1 quit %s\n",pret);
    return 0;
}

线程共享空间验证

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//pthread_t pthread_self(void);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_exit(void *rval_ptr);

int g_data=10;

void *func1(void *arg)
{
    printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
    printf("t1:pararm is %d\n",*((int*)arg));
    while(1){
            printf("%d\n",g_data++);
            sleep(1);
            if(g_data==3){
                  pthread_exit(NULL);
            }
    } 
}

void *func2(void *arg)
{
    printf("t2:%ld thread is create\n",(unsigned long)pthread_self());
    printf("t2:pararm is %d\n",*((int*)arg));
    while(1){
            printf("%d\n",g_data++);
            sleep(1);
    } 
}

int main()
{
    int ret;
    int pararm=100;
    pthread_t t1;
    pthread_t t2;
    
    ret=pthread_create(&t1,NULL,func1,(void*)&pararm);
    if(ret==0){
        printf("main:create t1 succees\n");
    }
    
    ret=pthread_create(&t1,NULL,func2,(void*)&pararm);
    if(ret==0){
        printf("main:create t1 succees\n");
    }

    printf("main:%ld\n",(unsigned long)pthread_self());
    while(1){
            printf("%d\n",g_data++);
            sleep(1);
    } 
    
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
  
    return 0;
}



互斥锁API

1.创建及销毁互斥锁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
// 返回:若成功返回0,否则返回错误编号
pthread_mutex_t *restrict mutex:const pthread_mutexattr_t *restrict attr:属性,一般为NULL

2.加锁及解锁

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
int pthread_mutex_trylock(pthread_mutex_t *restrict mutex);
int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);
// 返回:若成功返回0,否则返回错误编号
#include<stdio.h>
#include<pthread.h>
#include<unsitd.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//pthread_t pthread_self(void);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
//int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
//int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);

int g_data=0

pthread_mutex_t mutex;//定义锁

void *func1(void *arg)
{
     pthread_mutex_lock(&mutex);//加锁
     for(int i=0;i<5;i++){
         printf("t1:%ld thread is create\n",(unsigned long)pthraead_self());
         printf("t1:pararm is %d\n",*((int*)arg));
         sleep(1);
     }
     pthread_mutex_unlock(&mutex);//解锁
}

void *func2(void *arg)
{
     pthread_mutex_lock(&mutex);
     for(int i=0;i<5;i++){
         printf("t2:%ld thread is create\n",(unsigned long)pthraead_self());
         printf("t2:pararm is %d\n",*((int*)arg));
         sleep(1);
     }
     pthread_mutex_unlock(&mutex)
}

void *func3(void *arg)
{
     pthread_mutex_lock(&mutex);
     for(int i=0;i<5;i++){
         printf("t3:%ld thread is create\n",(unsigned long)pthraead_self());
         printf("t3:pararm is %d\n",*((int*)arg));
         sleep(1);
     }
     pthread_mutex_unlock(&mutex)
}

int main()
{
     int ret;
     int pararm=100;
     pthread_t t1;
     pthread_t t2;
     pthread_t t3;
     
     pthread_mutex_init(&mutex,NULL);//初始化锁
     
     ret=pthread_create(t1,NULL,func1,(void*)&pararm);
     if(ret==0){
            printf("create t1 success\n");
     }

     ret=pthread_create(t2,NULL,func2,(void*)&pararm);
     if(ret==0){
            printf("create t2 success\n");
     }

     ret=pthread_create(t3,NULL,func3,(void*)&pararm);
     if(ret==0){
            printf("create t1 success\n");
     }

     printf("main:%ld\n",(unsigned long)pthread_self());

     pthread_join(t1,NULL);
     pthread_join(t2,NULL);
     pthread_join(t3,NULL);
     
     pthread_mutex_destroy(&mutex);//收回锁
       
    
     return ;
}

互斥锁限制共享资源的访问

#include<stdio.h>
#include<pthread.h>
#include<unstid.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//pthread_t pthread_self(void);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
//int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
//int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);

int g_data=0;

pthread_mutex mutex;

void *func1(void *arg)
{
    printf("t1:%ld pthread is create\n",(unsigned long)pthread_self());
    printf("t1:pararm is %d\n",*((int*)arg));
    while(1){
           pthread_mutex_lock(&mutex);
           printf("%d\n",g_data++);
           sleep(1);
           if(g_data==3){
                  pthread_mutex_unlock(&mutex);
                  pthread_exit(NULL);
           }
    }
}

void *func2(void *arg)
{
    printf("t2:%ld pthread is create\n",(unsigned long)pthread_self());
    printf("t2:pararm is %d\n",*((int*)arg));
    while(1){
           printf("%d\n",g_data);
           pthread_mutex_lock(&mutex);
           g_data++;
           pthread_mutex_unlock(&mutex);
           sleep(1); 
    }
}

int  main()
{
     int ret;
     int pararm;
     pthread_t t1;
     pthread_t t2;
     
     pthread_mutex_init(&mutex,NULL);
     
     ret=pthread_create(&t1,NULL,func1,(void*)&pararm);
     if(ret==0){
           printf("create t1 success\n");
     }

     ret=pthread_create(&t2,NULL,func2,(void*)&pararm);
     if(ret==0){
           printf("create t2 success\n");
     }

     printf("main:%ld\n",(unsigned long)pthread_self());

     pthread_join(t1,NULL);
     pthread_join(t2,NULL);
     
     pthread_mutex_destroy(&mutex);
     return 0;
}

死锁

#include<stdio.h>
#include<pthread.h>
#include<unsitd.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//pthread_t pthread_self(void);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
//int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
//int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);

pthread_mutex_t mutex;
pthread_mutex_t mutex2;

void *func1(void *arg)
{
    pthread_mutex_lock(&mutex);
    sleep(1);
    pthread_mutex_lock(&mutex2);
    for(int i=0;i<5;i++){
         printf("t1:%ld\n",(unsigned long)pthread_self());
         printf("t1:pararm is %d\n",*((int *)arg));
         sleep(1);
    }
    pthread_mutex_unlock(&mutex);
}

void *func2(void *arg)
{
     pthread_mutex_lock(&mutex2);
     sleep(1);
     pthread_mutex_lock(&mutex);
     for(int i=0;i<5;i++){
         printf("t2:%ld\n",(unsigned long)pthread_self());
         printf("t2:pararm is %d\n",*((int *)arg));
         sleep(1);
    }
    pthread_mutex_unlock(&mutex);
}

void *func3(void *arg)
{
   pthread_mutex_lock(&mutex);
   for(int i=0;i<5;i++){
         printf("t3:%ld\n",(unsigned long)pthread_self());
         printf("t3:pararm is %d\n",*((int *)arg));
         sleep(1);
    }
   pthread_mutex_unlock(&mutex2);
}

int main()
{
    int ret;
    int pararm=100;
    pthread_t t1;
    pthread_t t2;
    pthread_t t3;
    
    pthread_mutex_init(&mutex,NULL);
    pthread_mutex_init(&mutex2,NULL);

    ret=pthread_create(t1,NULL,func1,(void*)&pararm);
    if(ret==0){
        printf("create t1 success\n");
    }

    ret=pthread_create(t2,NULL,func2,(void*)&pararm);
    if(ret==0){
        printf("create t1 success\n");
    }

    ret=pthread_create(t3,NULL,func3,(void*)&pararm);
    if(ret==0){
        printf("create t3 success\n");
    }

    printf("main:%ld\n",(unsigned long)pthread_self());

    pthread_join(&t1,NULL);
    pthread_join(&t2,NULL);
    pthread_join(&t3,NULL);
    
    pthread_mutex_destroy(&mutex);
    pthread_mutex_destroy(&mutex2);
   
     return 0;
}



条件控制实现线程同步


API


1.创建及销毁条件变量

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t cond);
// 返回:若成功返回0,否则返回错误编号


2.等待

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
// 返回:若成功返回0,否则返回错误编号


3.触发

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t *restrict cond);//常用
int pthread_cond_broadcast(pthread_cond_t cond);
// 返回:若成功返回0,否则返回错误编号

代码:

#include<stdio.h>
#include<pthread.h>
#include<unsitd.h>
#include<stdlib.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void a*(*start_rtn)(void *), void *restrict arg);
//int pthread_join(pthread_t thread, void **rval_ptr);
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
//int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
//int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//pthread_t pthread_self(void);
//int pthread_cond_destroy(pthread_cond_t cond);
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//int pthread_cond_signal(pthread_cond_t *restrict cond);

pthread_mutex_t mutex;
pthread_cond_t cond;

//静态初始化: pthread_cond_t = PTHREAD_COND_INITIALIZER
//静态初始化: pthread_mutex_t = PTHREAD_MUTEX_INITIALIZER
void *func1(void *arg)
{
      static int cnt=10;
      printf("t1:%ld pthread is create\n",(unsigned long)pthread_self());
      printf("t1:pararm is %d\n",*((int*)arg));
      while(1){
              pthread_cond_wait(&cond,&mutex);//等待
              if(g_data==3){
                     printf("t1 run=========================\n");
              }
              printf("t1:%d\n",g_data);
              g_data=0;
              sleep(1);
              if(cnt++=10){
                   exit(1);
              }
      }
}

void *func2(void *arg)
{
      printf("t1:%ld pthread is create\n",(unsigned long)pthread_self());
      printf("t1:pararm is %d\n",*((int*)arg));
      while(1){
              printf("t2:%d\n",g_data);
              pthread_mutex_lock(&mutex);
              printf("%d\n",g_data++);
              if(g_data==3){
                    pthread_cond_signal(&cond);//触发
              }
              pthread_mutex_unlock(&mutex);
              sleep(1);
      }
}


int main()
{
    int ret;
    int pararm=100;
    pthread_t t1;
    pthread_t t2;

    pthread_cond_init(&mutex,NULL);
    pthread_mutex_init(&cond,NULL);

    ret=pthread_create(&t1,NULL,func1,(void *)&pararm);
    if(ret==0){
          printf("create t1 success\n");
    }

    ret=pthread_create(&t2,NULL,func2,(void *)&pararm);
    if(ret==0){
          printf("create t1 success\n");
    }
    
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}




版权声明:本文为qq_47944751原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。