进程:进程是资源分配的最小单位,是程序执行时的实例,在程序运行时创建。
线程:线程是程序执行的最小单位,调度的基本单位,是进程的一个执行流。
并发和并行的区别并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。其中两种并发关系分别是同步和互斥。
同步:指进程间的关系是相互依赖。前一个进程的输出是后一个进程的输入。当前一个进程没有输出时,后一个进程必须等待。
互斥:进程之间相互排斥地使用临界资源(一次仅允许一个进程使用地共享资源)。
并行:指在同一时刻,有多条指令在多个处理器上同时执行。
同步和异步的区别同步:指进程间的关系是相互依赖。前一个进程的输出是后一个进程的输入。当前一个进程没有输出时,后一个进程必须等待。就是实时处理(如打电话)
异步:指进程间相互独立。执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。 就是分时处理(如收发短信)。
多线程编程 1.创建新线程 pthread_self函数: 获取线程ID- pthread_t pthread_self(void); 返回值:成功:0; 失败:无
- 线程ID:pthread_t类型,在Linux下为无符号整数(%lu),当前Linux中可理解为:typedef unsigned long int pthread_t
- int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
- 返回值:成功:0; 失败:错误号
- 参数1:传出参数,保存系统为我们分配好的线程ID
- 参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。
- 参数3:函数指针,指向线程主函数(线程体),新创建的线程从start_routine函数的地址开始运行,该函数运行结束,则线程结束。
- 参数4:线程主函数执行期间所使用的参数,有参数时输入参数的地址,如要传多个参数, 可以用结构封装。
-
//创建线程,返回线程序号和ID //Linux编译时加上 -lpthread //因为pthread并非Linux系统的默认库,而是POSIX线程库。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。 //gcc -o more_pthread more_pthread.c -lpthread #include
#include #include #include void *pth(void * arg); int main(int argc,char *argv[]) { int n,i; pthread_t tid; if(argc==2) { n=atoi(argv[1]); } for(i=0;i atoi()代表的是ascii to integer,即“把字符串转换成有符号数字”,举例如下: -
char a="-10"; char b="9"; int c=atoi(a)+atoi(b);
那么计算结果c=-10+9=-1。
-
int main(int argc,char * argv[]),表示的就是argc表示你使用这个程序时,输入的参数的个数,argv[]表示各个参数。
-
默认argc为1,argv[0]为程序名称。如果输入一个参数,则argc为2,argv[0]为程序名称,argv[1]为输入的那个参数。以此可推出,多个输入参数的情况。
- 运行结果
2. 单个线程退出 pthread_exit函数 : 将单个线程退出
- void pthread_exit(void *retval); 参数:retval表示线程退出状态,通常传NULL
//退出线程 #include#include #include #include void *pth(void * arg); int main(int argc,char *argv[]) { int n,i; pthread_t tid; if(argc==2) { n=atoi(argv[1]); } for(i=0;i 运行结果 线程中,禁止使用exit函数,会导致进程内所有线程全部退出。
3.等待线程结束 pthread_join函数: 阻塞等待线程退出,获取线程退出状态
- int pthread_join(pthread_t thread, void **retval)
- thread: 线程标识符,即线程ID,标识唯一线程
- retval: 用户定义的指针,用来存储被等待线程的返回值
//回收多个子线程 #include#include #include #include int var=10; void *pth(void * arg); int main(int argc,char *argv[]) { int i; pthread_t tid[5]; int *ret[5]; for(i=0;i<5;i++) { pthread_create(&tid[i], NULL, pth, (void *)i); } for(i=0;i<5;i++) { pthread_join(tid[i],(void**)&ret[i]); printf("=======%d ret=%dn",i,(int)ret[i]); } printf("i am main,main_pthread_id = %lut var=%dn",pthread_self(),var); sleep(i); return 0; } void *pth(void *arg) { int i; i=(int)arg; sleep(i); if(i==1) { var=20; printf("var=%dn",var); return (void*)var; } else if(i==3) { var=30; printf("i am %d pthread,id=%lu,var= %dn",i+1,pthread_self(),var); pthread_exit((void *)var); } else { printf("i am %d pthread,id=%lu,var= %dn",i+1,pthread_self(),var); pthread_exit((void *)var); } return NULL; } 运行结果
4.线程分离 pthread_detach函数: 实现线程分离
- int pthread_detach(pthread_t thread); 成功:0;失败:错误号
- 指定该状态,线程主动与主控线程断开关系。线程结束后(不会产生僵尸线程),其退出状态不由其他线程获取,而直接自己自动释放(自己清理掉PCB的残留资源)。网络、多线程服务器常用。
#include运行结果#include #include #include #include void *pth(void * arg); int main(int argc,char *argv[]) { int err; pthread_t tid; void *tret; #if 1 pthread_attr_t attr; //通过线程属性来设置游离态(分离态) pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); pthread_create(&tid,&attr,pth,NULL); #else pthread_create(&tid,NULL,pth,NULL); pthread_detach(tid); //让线程分离 ----自动退出,无系统残留资源 #endif while(1) { err=pthread_join(tid,&tret); printf("thread exit code=%dn",(int)tret); printf("========err=%dn",err); if(err!=0) { fprintf(stderr,"thread join err:%snn",strerror(err)); } else { fprintf(stderr,"thread join err:%snn",(int)tret); } sleep(2); } return 0; } void *pth(void *arg) { int n=3; while(n--) { printf("thread count %dn",n); sleep(1); } return (void *)1; }



