多线程具体实现(上)

简介: 多线程具体实现

小知识:

修改文件夹下所有文件的权限

sudo chmod -R 777 filename

filename为要修改的文件夹名字。-R应该是表示递归修改filename文件夹下所有文件的权限。

其实整个命令的形式是

sudo chmod -(代表类型)×××(所有者)×××(组用户)×××(其他用户)

线程

• 线程有时被称为轻量级进程(LightweightProcess,LWP),是程序执行流的最小单元。

• 线程是进程中的一个实体,是被系统独立调度和分派的基本单位,

• 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

引入线程前, 进程是资源分配的基本单位,也是调度的基本单位引入线程后, 进程是资源分配的基本单位, 线程是调度的基本单位

线程

• 允许程序执行不止一个任务的机制• 并行执行• 受操作系统异步调度, 是操作系统调度的最小单元,• 进程内的不同线程执行是同一程序的不同部分

主线程

• 线程可由进程创建,操作系统在创建进程时会创建一个主线程,程序main()函数是主线程的入口。

  1. 由于进程的地址空间是私有的,因此在进程间上下文切换时,系统开销比较大, 在同一个进程中创建的线程共享该进程的地址空间,
  2. 每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
  3. 线程也有就绪、阻塞和运行三种基本状态。
  4. Linux里同样用task_struct来描述一个线程。 线程和进程都参与统一的调度
  5. 多线程通过第三方的线程库来实现 New POSIX ThreadLibrary (NPTL)

多线程优点

经济实惠

• 分配的资源少、线程切换比进程切换快、维护线程的开销小

资源共享

• 线程共享它们所属进程的存储器和资源。

提高了响应速度

• 允许程序在它的一部分被阻塞或正在执行一个冗长 的操作时持续运行

提高了多处理机体系结构的利用率

• 在多CPU机器中,多线程提高了并发性

线程共享的资源

一个进程中的多个线程共享以下资源

• 可执行的指令

• 静态数据

• 进程中打开的文件描述符

信号处理函数

• 当前工作目录

• 用户ID

• 用户组ID

线程私有的资源

每个线程私有的资源如下

• 线程ID (TID)

• PC(程序计数器)和相关寄存器

• 堆栈

局部变量

返回地址

• 错误号(errno)

• 信号掩码和优先级

• 执行状态和属性

线程创建

NPTL线程库中提供了如下基本操作

• 创建线程

• 删除线程

• 控制线程

线程间同步和互斥机制

• 信号量

• 互斥锁

• 条件变量

pthread_create

#include <pthread.h>
 int  pthread_create(pthread_t *thread,  const pthread_attr_tattr,  
                             void * ( routine)(void *),  void *arg);

函数参数

thread:创建的线程

attr:指定线程的属性,NULL表示使用缺省属性

routine:线程执行的函数

arg: 传递给线程执行的函数的参数

函数返回值

成功:0

出错:-1

PTHREAD_CREATE_DETACHED分离线程没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源

PTHREAD _CREATE_JOINABLE线程的默认属性是非分离状态,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源

pthread_join

#include <pthread.h>
 int  pthread_join(pthread_t thread,  void **value_ptr)

线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!

函数参数

thread:要等待的线程

value_ptr:指针*value_ptr指向线程返回的参数

函数返回值

成功:0

出错:-1

pthread_cancel

#include <pthread.h>
int  pthread_cancel(pthread_t thread)

函数参数

thread:要取消的线程

函数返回值

成功:0

出错:-1

pthread_exit

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

函数参数

value_ptr:线程退出时返回的值

函数返回值

成功:0

出错:-1

在不终止整个进程的情况下,单个线程可以有三种方式停止其工作流并退出

1.线程从其工作函数中返回, 返回值是线程的退出码

2.线程可以被同一进程中的其他线程取消

3.线程自己调用pthread_exit

实例

#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void *thread1_func(void *arg)
{
    int    n;    
    for (n = 0; n < 30; n++) {
        sleep(1);
        printf("AAAAAAAAAA\n");
    }
    pthread_exit(NULL);
    //return NULL;
}
void *thread2_func(void *arg)
{
    int n;
    for (n = 0; n < 30; n++) {
        sleep(1);
        printf("BBBBBBBBBB\n");
    }
    return NULL;
}
int main(int argc, char *argv[])
{
    pthread_t tid1, tid2;
    if (pthread_create(&tid1, NULL, thread1_func, NULL) != 0) {
        perror("main: pthread_create thread_1 failed");
        return 1;
    } else {
        printf("main: pthread_create thread_1 succeed!\n");
    }
    if (pthread_create(&tid2, NULL, thread2_func, NULL) != 0) {
        perror("main: pthread_create thread_2 failed");
        return 1;
    } else {
        printf("main: pthread_create thread_2 succeed!\n");
    }
    if (pthread_join(tid1, NULL) != 0) {
        perror("main: pthread_join thread_1 failed");
    }
    if (pthread_join(tid2, NULL) != 0) {
        perror("main: pthread_join thread_2 failed");
    }
    printf("main is exiting.\n");
    return 0;
}

编译

gcc thread.c -o run -lpthread

进程调度有一定随机性

whereis pthread

线程查看

ps –efL

共用同一个pid,全局变量共享,打开的文件共享。

如果LWP与PID值相同则为主线程

•UID:用户ID

• PID:process id 进程id

• PPID: parent process id 父进程id

• LWP:表示这是个线程;要么是主线程(进程),要么是线程

• NLWP: num of light weight process 轻量级进程数量,即线程数量

• STIME: start time 启动时间TIME: 占用的CPU总时间

• TTY:该进程是在哪个终端运行的

• CMD:进程的启动命令

ps -ef f

• 用树形显示进程和线程

目录
相关文章
|
网络协议 安全
libev与多线程
libev与多线程
libev与多线程
|
6月前
多线程知识
多线程知识
27 1
|
7月前
|
Java API 调度
多线程知识篇
多线程知识篇
|
7月前
|
安全 Java C#
C#多线程详解
C#多线程详解
68 0
|
7月前
|
前端开发 Java
|
7月前
|
C#
[C#] 多线程的使用
[C#] 多线程的使用
49 0
多线程
java多线程是指在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。Java中所有变量都储存在主存中,对于所有线程都是共享的。Java中的多线程可以通过继承Thread类或者实现Runnable接口来创建,然后通过start()方法来启动线程。Java中的多线程可以提高程序的并发性和执行效率。
|
监控 Java API
多线程专题
多线程专题
|
调度 C++
多线程
多线程