线程的简单介绍与实现

来源:互联网 发布:数据库安全管理制度 编辑:程序博客网 时间:2024/06/05 06:00
线程和进程
          线程:是系统调度的基本单位 
          进程:是系统分配资源的基本单位

为了任务处理linux系统引入了进程的概念去实现多任务处理:

  进程的特点:1.进程间的内存空间是互相独立的。
                 2.进程是系统分配资源的最少单位 -》每创建一个进程系统都会进行一次资源分配
                         3.因为进程间的空间的独立的,假如进程之间需要相互协作的话就必须,使用管道,消息队列,信号,共享内存。。。等通信方式进程数据交换

如何使用线程?
注意编译线程时必须加入线程库:  -lpthread
例子:gcc pthread.c -o pthread -lpthread 


线程需要注意的事项:
1.在线程中,主线程死亡则所有子线程也会死亡!
2.子线程与主线程,共享数据段与堆空间,当全局变量与局部变量同门时,线程优先使用局部变量。(所以线程间的通信,只有使用全局变量即可)
3.线程是不会向操作系统申请资源的,他只会从主线程中拿到自己的虚拟栈  (大大的节省内存空间)

线程的使用:
1. pthread_create---》线程创建
头文件:
        #include <pthread.h>
函数原型:
       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数一:pthread_t *thread -》线程PID。-》每一个线程他都有自己的一个唯一标识
参数二:线程属性  -》NULL  默认属性即可 
参数三:重点!!!
        void *(*start_routine) (void *)  -》指针,指向一个函数 void * func(void *atg)
任务函数,类型必须为void * func(void *atg);
参数四:传递给任务函数的参数

2.pthread_join -- -》线程等待数
头文件:
        #include <pthread.h>
函数原型:
       int pthread_join(pthread_t thread, void **retval);  -》回收线程的资源  
参数一:等待的线程PID 
参数二:保存线程的退出信息
返回值:成功返回0  失败返回一个错误号    
    

3. pthread_detach ---》设置分离属性:-》一般线程创建后就马上设置为分离属性
   int pthread_detach(pthread_t thread); 》假如线程设置为分离属性后,pthread_join函数就不会等待
参数一。线程PID
返回值:成功返回0,失败返回错误号


4.pthread_exit  ---》线程退出函数
头文件:
         #include <pthread.h>
函数原型:
         void pthread_exit(void *retval);
参数一:把退出信息存放到该地址上,会传递给pthread_join的第二个参数


5. pthread_cancel --->线程取消函数:-》杀死线程
头文件:
       #include <pthread.h>
函数原型:
       int pthread_cancel(pthread_t thread);
参数一:要杀死的线程PID
成功:返回0 失败发回错误号

6. pthread_setcancelstate --->开启或关闭线程取消信号:
头文件:
        #include <pthread.h>
函数原型:
         int pthread_setcancelstate(int state, int *oldstate);
参数一:开启或关闭线程取消信号
      开启  PTHREAD_CANCEL_ENABLE
      关闭  PTHREAD_CANCEL_DISABLE
参数二:原来开启或关闭的状态
成功:返回0  失败返回错误号  

------------------------------------------------------------------------------------------------------------------
练习:使用线程函数
#include <stdio.h>#include <pthread.h>int i=100;void *func(void *arg){int i=0;//同时存在全局变量和局部变量的情况下,优先使用局部变量while(1){//pthread_exit(arg);pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);printf("i=%d\n",i++);sleep(1);}}int main(){pthread_t tid;pthread_create(&tid,NULL,func,NULL);pthread_detach(tid);int j=0;while(1){if(j==7)pthread_cancel(tid);printf("j=%d\n",j++);sleep(1);}}



-------------------------------------------------------------------------------------------------------------------------------------
练习:线程回收和退出
#include <unistd.h>#include <stdio.h>#include <pthread.h>      static int abc;void *thread_fun(void *p){static int abc1;while (1){sleep(1);printf("world %d\n", abc++);if (abc > 4)pthread_exit((void *)(&abc));}return NULL;}int main(int argc, char const *argv[]){static int abc2;void *retval;int fd;int res;pthread_t tid;//创建一个线程res = pthread_create(&tid, NULL, thread_fun, NULL);if (res < 0){perror ("thread create");return -1;}pthread_join(tid, &retval);printf("%d\n", *((int *)retval));return 0;}



------------------------------线程的同步与互斥------------------------------------
sudo apt-get install manpages-posix-dev   线程锁库安装

头文件:
         #include <pthread.h>
初始化线程锁:
    int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
参数一:线程锁的ID
参数二:线程锁的属性

上锁:
       int pthread_mutex_lock(pthread_mutex_t *mutex);  上锁操作 -》“死等”上锁后他会一直等待解锁操作,直达进程死亡
参数一:线程锁ID
返回值:成功返回0  失败返回错误码

       int pthread_mutex_trylock(pthread_mutex_t *mutex); 尝试上锁,他不会死等,只会立即返回上锁结果

解锁:
      int pthread_mutex_unlock(pthread_mutex_t *mutex);

销毁锁:
      int pthread_mutex_destroy(pthread_mutex_t *mutex);
-------------------------------------------------------------------------------------------------------------------------------------
练习:线程锁的使用
#include <stdio.h>#include <pthread.h>int i=0;//全局变量pthread_mutex_t mutex; //所以线程都可用这把锁pthread_mutex_t mutex1; void *func(void *arg) { while(1){//上锁pthread_mutex_lock(&mutex1);printf("ifunc=%d\n",i++);//解锁    pthread_mutex_unlock(&mutex);//sleep(1);} }//使用线程锁达到同步的目的int main(){ //创建线程   pthread_t  pid;       pthread_create(&pid,NULL,func,NULL);   //初始化线程锁 1    pthread_mutex_init(&mutex,NULL);   //初始化线程锁 2   pthread_mutex_init(&mutex1,NULL);   while(1){//上锁pthread_mutex_lock(&mutex);printf("i=%d\n",i++);//解锁    pthread_mutex_unlock(&mutex1);//sleep(1);}}




-------------------------------------线程锁之条件变量----------------------------
初始化条件变量:
       int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
   参数一:条件变量ID
   参数二:条件变量属性
   返回值:返回0 ,失败返回错误号
   
//销毁条件变量   
        int pthread_cond_destroy(pthread_cond_t *cond);
参数一:要销毁的条件变量ID
返回值:返回0 ,失败返回错误号

等待条件到来:
         int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

发送条件信号:
头文件:
       #include <pthread.h>
函数原型
       int pthread_cond_broadcast(pthread_cond_t *cond); ---》给所有条件变量发送信号
       int pthread_cond_signal(pthread_cond_t *cond); ---》 发送一条条件信号
-------------------------------------------------------------------------------------------------------------------------------------
练习:条件变量的使用
#include <stdio.h>#include <pthread.h>int i=0;//全局变量pthread_mutex_t mutex; //所以线程都可用这把锁pthread_cond_t cond;   //所有线程利用这个条件变量ID void *func(void *arg) { while(1){//上锁printf("6666\n");pthread_mutex_lock(&mutex);//等待条件变量信号printf("123456\n");pthread_cond_wait(&cond,&mutex); //利用锁 把线程锁在该条件变量上//接受到条件后他就不会阻塞printf("ifunc=%d\n",i++);//解锁    pthread_mutex_unlock(&mutex);sleep(1);} }//使用线程锁达到同步的目的int main(){ //创建线程   pthread_t  pid;       pthread_create(&pid,NULL,func,NULL);   //初始化线程锁    pthread_mutex_init(&mutex,NULL);     //初始化条件变量   pthread_cond_init(&cond,NULL);   while(1){//上锁pthread_mutex_lock(&mutex);printf("i=%d\n",i++);if(i==5){//发送条件信号pthread_cond_signal(&cond);}//解锁    pthread_mutex_unlock(&mutex);sleep(1);}}




原创粉丝点击