赞
踩
每个进程都拥有自己的数据段、代码段和堆栈段,这就造成进程在进行创建、切换、撤销操作时,需要较大的系统开销。
为了减少系统开销,从进程中演化出了线程。
线程存在于进程中,共享进程的资源。
线程是进程中的独立控制流,由环境(包括寄存器组和程序计数器)和一系列的执行指令组成。
每个进程有一个地址空间、和一个控制线程。
使用多线程设计实现高并发的效果(重点)
就像每个进程都有一个进程号一样,每个线程也有一个线程号。
进程号用pid_t数据类型表示,是一个非负整数。线程号则用pthread_t数据类型来表示。
注意:
进程号在整个系统中是唯一的,但线程号不同,线程号只在它所属的进程环境中有效。
有的系统在实现pthread_t的时候,用一个结构体来表示,所以在可移植的操作系统实现不能把它做为整数处理。
#include <pthread.h>
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(start_routine)(void),
void * arg);
参数:
返回值:成功返回0,失败返回非0;
注意:
与fork不同的是pthread_create创建的线程不与父线程在同一点开始运行,而是从指定的函数开始运行,该函数运行完后,该线程也就退出了。
线程依赖进程存在的,如果创建线程的进程结束了,线程也就结束了。
线程函数的程序在pthread库中,故链接时要加上参数-lpthread。
#include <stdio.h> #include <unistd.h> #include <pthread.h> int var = 8; /* 线程函数:1*/ void *thread_1(void *arg) { while (1) { printf("This is my new thread1 var++ %d\n"); var++; sleep(1); } return NULL; } /*线程函数:2*/ void *thread_2(void *arg) { while (1) { printf("This is my new thread2 var = %d\n",var);/* code */ sleep(1); } return NULL; } int main() { /*创建线程号*/ pthread_t tid1,tid2; /*创建两个线程*/ pthread_create(&tid1,NULL,thread_1,NULL); pthread_create(&tid1,NULL,thread_2,NULL); while (1) { /* code */ } return 0; }
分析:var 是 进程资源,两个线程共享改进程资源,一个线程使var++,另一个线程打印var的值
#include <pthread.h>
int pthread _ join(pthread_t thread, void **value_ptr);
功能:等待子线程结束,并回收子线程资源(阻塞状态)
参数:
返回值:成功返回0,失败返回非0。
#include <stdio.h> #include <unistd.h> #include <pthread.h> void *thread(void *arg) { int i; static int test = 1213; for( i = 0; i < 5; i++) { printf("I am runing \n"); } /*退出函数要求(void *) 退出后带返回值test*/ pthread_exit( (void *) (&test) ); return NULL; } int main(int argc,char * argv[]) { void *vaule_ptr; int ret = 0; pthread_t tid1; /*创建线程*/ ret = pthread_create(&tid1,NULL,thread,NULL); if(ret != 0) { perror("pthread_create"); } /*等待一个子线程退出,退出后回收线程资源*/ pthread_join(tid1,&vaule_ptr); /*打印线程结束后所带回来的返回值*/ printf("vaule_ptr = %d\n",*( (int *)vaule_ptr) ); sleep(1); printf("I am leaving \n"); while(1); return 0; }
注意:
创建一个线程后应回收其资源,但使用pthread_join函数会使调用者阻塞,故Linux提供了线程分离函数:pthread_detach。
#include <pthread.h>
int pthread_detach(pthread_t thread);
功能:使调用线程与当前进程分离,使其成为一个独立的线程,该线程终止时,系统将自动回收它的资源。
参数:thread:线程ID
返回值:成功:返回0,失败返回非0。
#include <stdio.h> #include <unistd.h> #include <pthread.h> void *thread(void *arg) { int i; static int test = 1213; for( i = 0; i < 5; i++) { printf("I am runing \n"); sleep(1); } return NULL; } int main(int argc,char * argv[]) { int ret = 0; pthread_t tid1; /*创建线程*/ ret = pthread_create(&tid1,NULL,thread,NULL); if(ret != 0) { perror("pthread_create"); } /*分离 tid1 的线程*/ pthread_detach(tid1); /*等待tid1线程结束,回收资源*/ pthread_join(tid1,NULL); /*线程一旦分离,pthread_jojn()将不会等待*/ /*最一开始打印*/ printf(" after jion \n "); sleep(3);//线程打印 printf("I am leaving \n"); return 0;//进程结束 线程也结束 }
在进程中我们可以调用exit函数或_exit函数来结束进程,在一个线程中我们可以通过以下三种在不终止整个进程的情况下停止它的控制流。
#include <pthread.h>
void pthread_exit(void *value_ptr);
功能:
使调用线程退出。
参数:
int pthread_cancel(pthread_t thread);
功能:取消线程:是指取消一个正在执行线程的操作。
参数:thread:目标线程ID。
返回值:成功返回 0,失败返回出错编号
注意:
在Linux系统下,线程默认可以被取消。编程时可以通过pthread_setcancelstate函数设置线程是否可以被取消。
pthread_setcancelstate(int state,int *old_state);
#include <unistd.h> #include <pthread.h> void *thread_cancel(void *arg) { //pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);//禁能接收取消信号 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);//使能接收取消信号 //ENABLE使能:等线程接收到取消信号就退出 //DIISABLE禁能:不接收取消信号 while(1) { printf("This is my new thread_cancel\n"); sleep(1); } return NULL; } int main(int argc ,char *argv[]) { int ret = 0; pthread_t tid1; ret = pthread_create(&tid1,NULL,thread_cancel,NULL); if(ret != 0) { perror("pthread_create"); } sleep(3); pthread_cancel(tid1); pthread_join(tid1,NULL); return 0; }
注意:
#include <pthread.h>
void pthread_cleanup_push(void (routine)(void), void *arg);
功能: 将清除函数压栈。即注册清理函数。
参数:
#include <pthread.h>
void pthread_cleanup_pop(int execute);
功能:将清除函数弹栈,即删除清理函数。
参数:
当线程执行以下动作时会调用清理函数:
注意:
pthread_cleanup_pop()函数、pthread_cleanup_push()必须配对使用。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> void cleanup(void *arg) { printf("clean ip ptr = %s\n",(char *)arg); /*释放申请的堆区内存*/ free( (char *)arg); } void *thread(void *arg) { char *ptr = NULL; printf("This is new thread\n"); /* 在堆区申请100个字节的空间 */ ptr = (char *)malloc(100); /*把cleanup函数入栈*/ pthread_cleanup_push(cleanup,(void *)(ptr)); /* 清空申请空间 */ bzero(ptr,100); /* 填充申请空间 */ strcpy(ptr,"memory form malloc"); printf("before exit\n"); /* 退出线程 */ pthread_exit(NULL); sleep(3); printf("before pop\n"); pthread_cleanup_pop(0); //pthread_cleanup_pop(1); return NULL; } int main(int argc,char *argv[]) { int ret = 0; pthread_t tid1; /* 创建线程 */ ret = pthread_create(&tid1,NULL,thread,NULL); if(ret != 0) { perror("pthread_create"); } /* 等待线程的结束 */ pthread_join(tid1,NULL); printf("Process is dying\n"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。