线程的创建,等待与终止

一.线程的创建

  1. 基础知识

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。

线程也有就绪阻塞运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

在单个程序中同时运行多个线程完成不同的工作,称为多线程

2. 相关函数

3. 代码实现

//create.c
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<pthread.h>
  4 
  5 pthread_t tid;
  6 void* thread_run(void* val)
  7 {
  8     printf("%s:pid is :%d,tid is:%u\n", (char*)val,(int)getpid(),(unsigned long long)pthread_self());
  9 }
 10 int main()
 11 {
 12     int err=pthread_create(&tid,NULL,thread_run,"other thread run");
 13     if(err!=0)
 14     {
 15         printf("create thread error! info is:%s\n",strerror(err));
 16         exit(err);
 17     }
 18     printf("main thread run:pid is:%d,tid is:%u\n",(int)getpid(),(unsigned long long)pthread_self());
 19     sleep(5);
 20     return 0;
 21 }
 
 //makefile
  1 create:create.c
  2     gcc -o [email protected] $^ -lpthread
  3 .PHONY:clean
  4 clean:
  5     rm -f create

输出结果:

结果分析:

1.属于同一进程的不同线程可通过getpid()和pthread_self()得到相同的pid与不同的tid。

2.pthread_create()的错误码没有保存在error中,所以不能通过perror()得到,可通strerror()把错误码转换成错误信息再打印。

3.任意一个线程调用了exit()或_exit(),该进程所有线程将结束。从main()函数中return相当于调用了exit。

4.为了防止新创建的线程还没有执行就终止,在main函数return前sleep了1秒,但不是很好的办法,因为1秒内,不一定会调用新线程。下面在终止线程上进行优化。

二.线程的终止

  1. 基础知识

只终止某个线程而不终止整个进程,可以有三种方法:

1. 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit。

2. 一个线程可以调用pthread_cancel终止同一进程中的另一个线程。

3. 线程可以调用pthread_exit终止自己。

注意:pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

2.函数

pthread_cancel

pthread_exit

三.线程等待

  1. 函数

调用该函数的线程将挂起等待,直到id为thread的线程终止。

  1. 基础知识:

thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:

1. 如果thread线程通过return返回,value_ptr所指向的单元存放的是thread线程函数的返回值。

2. 如果thread线程被别的线程调用pthread_cancel异常终掉,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED。

3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ptr

2.代码实现:

//destory.c
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<pthread.h>
  4 
  5 void* thread1(void* val)
  6 {
  7     printf("thread 1 returning...\n");
  8     return (void*)1;
  9 }
 10 void* thread2(void* val)
 11 {
 12     printf("thread 2 exiting...\n");
 13     pthread_exit((void*)2);
 14 }
 15 void* thread3(void* val)
 16 {
 17     while(1)
 18     {
 19         printf("pthread 3 is running,wait for be canceled...\n");
 20         sleep(1);
 21     }
 22     return NULL;
 23 }
 24 int main()
 25 {
 26     pthread_t tid;
 27     void* tret;
 28 
 29     //thread 1 
 30     pthread_create(&tid,NULL,thread1,NULL);
 31     pthread_join(tid,&tret);
 32     printf("thread 1 return:tid:%u,return code is:%d\n",(unsigned long)tid,tret);
 33 
 34     //thread 2
 35     pthread_create(&tid,NULL,thread2,NULL);
 36     pthread_join(tid,&tret);
 37     printf("thread 2 pthread_exit:tid:%u,return code is:%d\n",(unsigned long)tid,tret);
 38 
 39     //thread 3
 40     pthread_create(&tid,NULL,thread3,NULL);
 41     sleep(3);
 42     pthread_cancel(tid);
 43     pthread_join(tid,&tret);
 44     printf("thread 3 pthrea_cancel:tid:%u,return code is:%d\n",(unsigned long)tid,tret);
 45 
 46     return 0;
 47 }
 
 //makefile
  1 destroy:destroy.c
  2     gcc -o [email protected] $^ -lpthread
  3 .PHONY:clean
  4 clean:
  5     rm -f destroy

输出结果:

时间: 2024-10-28 23:27:21

线程的创建,等待与终止的相关文章

线程的创建、终止、等待

线程的概念: 同一进程的多个线程共享同一地址空间,因此Text Segment.Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境: 1. 文件描述符表 2. 每种信号的处理方式(SIG_IGN.SIG_DFL或者自定义的信号处理函数) 3. 当前工作目录 4. 用户id和组id 但有些资源是每个线程各有一份的: 1. 线程id 2. 上下文,包括各种寄存器的值.程序计数器和栈指针 3

java 加入一个线程、创建有响应的用户界面 。 示例代码

javajava 加入一个线程.创建有响应的用户界面 . 示例代码 来自thinking in java 4 21章  部分代码  目录21.2.11 thinking in java 4免费下载:http://download.csdn.net/detail/liangrui1988/7580155 package org.rui.thread.concurrent; /** * 加入一个线程 * 一个线程可以在其他线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行

Linux C线程的创建和使用 [转]

1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中 去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多 线程就意味着多进程.现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux. 为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比

【归纳整理】Liunx下的进程管理(三),多进程的等待和终止

进程的正常退出 ------------------ 1. 从main函数中return. int main (...) { ... return x; } 等价于: int main (...) { ... exit (x); } 2. 调用标准C语言的exit函数. #include <stdlib.h> void exit (int status); 1) 调用进程退出, 其父进程调用wait/waitpid函数返回status的低8位. 2) 进程退出之前, 先调用所有事先通过atex

管理线程之创建线程

主要的线程管理包含:1.创建线程.2.等待它结束或在后台执行. 3.向线程函数传递參数.更改线程对象全部权.4.选择线程和使用特定线程. 创建线程 线程在创建线程对象时開始执行,创建线程对象使用std::thread.像上节最后那个函数一样.最简单的情况是线程对象创建后执行一个无返回值.无參数的函数. 这个函数在线程中执行直到返回,这时线程终止. 想一下最复杂的情况,线程执行的函数可能是个函数对象.须要传递參数,执行一系列独立的操作.这些操作须要系统的一些信息,直到接收到某个信号终止. 线程执行

漫谈并发编程(二):java线程的创建与基本控制

java线程的创建 定义任务 在java中使用任务这个名词来表示一个线程控制流的代码段,用Runnable接口来标记一个任务,该接口的run方法为线程执行的代码段. public class LiftOff implements Runnable { protected int countDown = 10; private static int taskCount = 0; private final int id = taskCount++; public void run() { whil

线程的创建和控制

线程的定义:线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源.一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行.由于线程之间的相互制约,致使线程在运行中呈现出间断性.线程也有就

linux内核线程的创建与销毁

linux将创建内核线程的工作交给了一个专门的内核线程kthreadd来完成,该线程会检查全局链表kthread_create_list,如果为NULL,就会调schedule()放弃cpu进入睡眠状态,否则就取下该链表中的一项创建对应的线程.本文就从khtreadd内核线程的创建开始来展示一下内核线程的创建过程.1 kthreaddlinux2.6.30,创建内核线程是通过kethradd内核守护线程来完成的,虽然机制上有所变化,但是最终还是调用do_fork来完成线程的创建.Kthreadd

Java总结(九)——(线程模块 一(线程的创建(方法一)与启动,线程状态与生命周期,进程与线程))

一.进程与线程 进程:每一个独立运行的程序称为一个进程 线程:线程时一个进程内部的一条执行路径,Java虚拟机允许程序并发的运行多个执行路径 *进程中执行运算的最小单位-->线程<--处理机分配 进程与线程的区别: (1)进程有独立的运行地址空间,一个进程崩溃后不会影响到其他的进程,而线程只是 一个进程中的一个执行路径,如果有一条线程奔溃了,可能会影响到进程中的的其他线程 (2)线程有自己的栈和局部变量,多个线程共享同一进程的地址空间 (3)一个进程至少有一个线程 多线程 (1)多线程 就是在