Linux基础第二章,Linux基础第楚辞

by admin on 2019年4月3日

第一章 概述

Linux基础第三章 概述,linux第叁章概述

第一章 概述

前言

在此以前钻探了经过,领会多少个经过能做壹件工作,要是想同时处理多件业务,那么必要四个进程,可是经过间很不便利的少数是,进度间的数据沟通仿佛未有那么方便。Linux提供线程成效,能在贰个经过中,处理多职务,而且线程之间的数据是统统共享的。

线程也有PCB,它的PCB和进程的PCB结构完全1致,只是它里面保存的虚拟地址空间和开创它的历程的虚拟地址空间完全保持一致。

1.1 前言

本章商讨系统的定义,从硬件、操作系统角度更是深远的通晓放区救济总会括机体系,并相当的慢浏览Linux系统提供的劳务。

第一章 概述

1.1 前言

本章商量系统的概念,从硬件、操作系统角度更是深切的知情计算机种类,并非常的慢浏览Linux系统提供的劳务。

线程的创造

通过pthread_create函数可以创立叁个线程,被创设的线程的例程,就是2个新的施行命令连串了。

#include <pthread.h>

void* thread_func(void* p )
{
    return NULL;
}

int main()
{
    pthread_t tid;

    pthread_create(&tid, NULL, thread_func, NULL);
    printf("tid=%d\n", (int)tid);
    pthread_create(&tid, NULL, thread_func, NULL);
    printf("tid=%d\n", (int)tid);
    pthread_create(&tid, NULL, thread_func, NULL);
    printf("tid=%d\n", (int)tid);
    pthread_create(&tid, NULL, thread_func, NULL);
    printf("tid=%d\n", (int)tid);

    getchar();
}

 

 

Compile and link with -lpthread.

 

补充
intptr_t是1种整型,它的长短依赖机器位长,也就象征它的长度和指针的长度一样的。

壹.贰 系统结合

 home88一必发 1

 

1.1 前言

本章研究系统的概念,从硬件、操作系统角度更是深厚的掌握放区救济总会结机种类,并神速浏览Linux系统提供的服务。

壹.二 系统一整合合

 home88一必发 2

 

 线程标识

线程使用pthread_t来标识线程,它也是三个非负整数,由系统一分配配,保障在进程范围内唯一。pthread_t即便在Linux下是非负整数,不过在别的平台下不肯定是,所以相比线程号是还是不是想等,应该用pthread_equal

此外三个函数都能够调用pthread_self来取得方今代码运维的线程。

一.叁 操作系统和应用程序

操作系统那几个词语有2意性,有时候指内核,有时候指内核和系列工具软件的3结合。

 

 home88一必发 3

 

 

操作系统是治本种类硬件的软件。操作系统是直接运维在裸机之上。别的APP运维在操作系统之上。

操作系统本人提供操作接口,支持用户通过该接口来操作
系统,然而系统自己提供的作用,不足于完毕用户须求时,则供给成本应用程序来拓展系统功效。

发行版:
今非昔比的商行利用Linux内核,加上本身开发的系统工具软件,壹起公布的Linux操作系统版本。

1.二 系统组合

1.3 操作系统和应用程序

操作系统那几个词语有二意性,有时候指内核,有时候指内核和系统工具软件的整合。

 

 home88一必发 4

 

 

操作系统是管理种类硬件的软件。操作系统是一向运营在裸机之上。其余使用软件运转在操作系统之上。

操作系统自己提供操作接口,支持用户通过该接口来操作
系统,可是系统本身提供的效果,不足于完结用户必要时,则供给开支应用程序来拓展系统机能。

发行版:
差别的合营社选用Linux内核,加上自身开支的种类工具软件,1起公布的Linux操作系统版本。

线程终止

终止方式  
例程返回 正常退出
调用pthread_exit 正常退出
响应pthread_cancel 异常退出

注意:

  • 在线程里调用exit是退出整个经过。

  • 在四线程的进度中,主线程调用pthread_exit,进程并不会脱离,它的其余线程依然在推行,不过主线程已经退出了。

  • 表示:主线程和此外线程是大致是如出1辙的。

  • 不雷同的是,假使主线程的main函数return了,那么任何线程也终结了,借使别的线程的入口函数return了,主线程不会随着截止。

1.四 运转和登陆

home88一必发 5

安排文件:
/etc/profile:系统运行时被实施
~/.bashrc:用户登6时会调用

 home88一必发 6  

1.四 运维和登6

home88一必发 7

配置文件:
/etc/profile:系统运营时被实践
~/.bashrc:用户登陆时会调用

线程的回收

线程退出之后,它的PCB依然在基础中存在,等着其余线程来获取它的运营结果,能够经过pthread_join来回收线程。从那个角度看,线程和经过大概,不过跟进度不一样的时,线程未有父线程的概念,同三个历程内的其余线程都足以来回收它的运维结果。

pthread_join会卡住调用它的线程,平昔到被join的线程甘休截止。

pthread_joinwait/waitpid壹律,也是阻塞的调用,它除了有回收PCB的效劳,也有等待线程结束的服从。

1.5 文件

文本是2个器重的定义,一般定义为音信的集合。总结机做为音讯处理的机械,文件是计算机处理的指标。

在Unix和Linux系统中,泛化了文本的定义,设备也被架空成文件对象来进展操作。

数码的聚众叫做文件。
IT行业处理音讯:转换,传输,存款和储蓄

1.三 操作系统和应用程序

操作系统这个词语有二意性,有时候指内核,有时候指内核和系统工具软件的组合。

   home88一必发 8    

Linux基础第二章,Linux基础第楚辞。操作系统是管理体系硬件的软件。操作系统是直接运转在裸机之上。别的应用软件运营在操作系统之上。

操作系统自个儿提供操作接口,协理用户通过该接口来操作
系统,然则系统本人提供的效用,不足于完结用户须求时,则须要开发应用程序来拓展系统机能。

发行版:
差异的营业所使用Linux内核,加上本身付出的类别工具软件,一起发表的Linux操作系统版本。

1.5 文件

文本是一个主要的概念,壹般定义为消息的集合。总计机做为新闻处理的机械,文件是电脑处理的靶子。

在Unix和Linux系统中,泛化了文本的概念,设备也被架空成文件对象来拓展操作。

多少的聚众叫做文件。
IT行业处理音信:转换,传输,存款和储蓄

线程的接纳情状

1.6 程序、进程

home88一必发 9

一.四 运行和登陆

home88一必发 10

配备文件:
/etc/profile:系统运行时被实施
~/.bashrc:用户登陆时会调用

1.6 程序、进程

home88一必发 11

 客户端使用景况

一般的话,线程用于相比复杂的多职务场景,比如:

 home88一必发 12

如此那般主线程能够基础处理主线程的业务,不至于被纵横交叉的职责阻塞。比如:

 

home88一必发 13

如此聊天界面不会卡死在那里,不然假若互连网状态很差,有非常大希望引致界面卡死。

一.七 错误处理

系统调用在相似景观下重回整数,并且0表示成功,小于0代表退步。当系统调用重临失利时,能够透过errno得到错误嘛,通过strerror获取错误演讲,大概直接通过perror在正儿8经错误文件中,输出错误音信。

 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
// 通过open重临的平头,在linux中有个越发的名字
// 叫文件讲述符 file description 简称fd

int fd = open(“a.txt”, O_WRONLY|O_CREAT|O_EXCL, 0777);
if(fd < 0)//表示文件打开战败
{
perror(“open”);
return 0;
}

// 把指针放到文件开始
lseek(fd, 0, SEEK_SET);

// 对文本举办操作
write(fd, “hello”, 5);

// 关闭文件,尽管不倒闭,内部存款和储蓄器会泄漏
// 当进度退出时,未关门的公文少禽自行关闭
close(fd);

}

1.5 文件

文件是二个首要的定义,①般定义为音讯的集聚。总计机做为音信处理的机器,文件是总结机处理的靶子。

在Unix和Linux系统中,泛化了文件的定义,设备也被架空成文件对象来展开操作。

数据的集合叫做文件。
IT行业处理消息:转换,传输,存款和储蓄

1.七 错误处理

系统调用在一般景况下归来整数,并且0表示成功,小于0表示失利。当系统调用重临失利时,能够通过errno得到错误嘛,通过strerror获取错误演讲,也许直接通过perror在规范错误文件中,输出错误音信。

 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
// 通过open再次来到的平头,在linux中有个尤其的名字
// 叫文件讲述符 file description 简称fd

int fd = open(“a.txt”, O_WRONLY|O_CREAT|O_EXCL, 0777);
if(fd < 0)//表示文件打开退步
{
perror(“open”);
return 0;
}

// 把指针放到文件开首
lseek(fd, 0, SEEK_SET);

// 对文本实行操作
write(fd, “hello”, 5);

// 关闭文件,假使不关门,内部存款和储蓄器会泄漏
// 当进度退出时,未关门的文书会自动关闭
close(fd);

}

服务器使用处境

服务器1般的流程如下:

 home88一必发 14

在服务器上,多个线程来处理任何工艺流程,会招致处理流程极慢,导致主线程不能及时吸收接纳报文。1般会选择子线程来狠抓际的行事,而主线程只负责接收报文。

home88一必发 15

突发性为了拉长处理效用,会使用线程池

 

 

1.捌 用户、组、文件权限

Linux是多用户系统,支持多少个用户同时登陆系统。
为了安全起见,须要对系统的权能加于规范。

1.6 程序、进程

一.八 用户、组、文件权限

Linux是多用户系统,帮助八个用户同时登陆系统。
home88一必发,为了安全起见,要求对系统的权限加于规范。

柒.七 线程的一起

任凭上述那种情景,都有1个报文队列大概新闻队列,1般那几个队列是贰个链表,主线程需求往链表中添加多少,而子线程从链表获取数据。Linux基础第二章,Linux基础第楚辞。三个线程同时操作二个全局变量是不安全的,应该防止不安全的访问。无论那种全局变量是数组、链表、依旧一个回顾的变量。

线程A:i = i + 1;
线程B:i = i + 1;

1.9 信号

信号是进度通讯的一种手段,有个别进度收到非频域信号,该实信号可财富于内核、来自其余进度可能来自用户操作。例如:当用户按下ctrl+c时,其实是给前台进度发送了2个信号。

home88一必发 16

1.9 信号

时限信号是进程通讯的一种手段,有个别进度收到时域信号,该随机信号恐怕来自内核、来自别的进程可能来自用户操作。例如:当用户按下ctrl+c时,其实是给前台进度发送了贰个功率信号。

七.七.一 不安全的案例

  • 二十四线程操作3个全局变量

#include <stdio.h>

#include <signal.h>

#include <pthread.h>

 

int result=0;

 

void add()

{

    int i;

    for(i=0; i<100000; ++i)

    {

        result++;

    }

}

 

void* thread_func(void* p)

{

    add();

    return NULL;

}

 

int main()

{

    pthread_t t1;

    pthread_t t2;

 

    pthread_create(&t1, NULL, thread_func, NULL);

    pthread_create(&t2, NULL, thread_func, NULL);

 

    pthread_join(t1, NULL);

    pthread_join(t2, NULL);

 

    printf(“%d\n”, result);

    return 0;

}

  • 不安全的生产者消费者模型

#include <list>

 

struct task_t

{

    int task;

};

 

list<task_t*> queue;

 

void* work_thread(void* arg)

{

    while(1)

    {

        if(queue.size() == 0) continue;

 

        task_t* task = *queue.begin();

        queue.pop_front();

 

        printf(“task value is %d\n”, task->task);

        delete task;

    }

}

 

void main(int argc, char* argv[])

{

    pthread_t tid;

    pthread_create(&tid, NULL, work_thread, NULL);

 

    while(1)

    {

        int i;

        cin >> i;

        task_t* task = new task_t;

        task->task = i;

 

        queue.push_back(task);

    }

 

    pthread_join(tid, NULL);

}

壹.10 系统调用和库函数

学学Linux系统开发接口时,程序员也须要学习壹般常用的第壹方库,来实行程序员的编制程序能力。

 

home88一必发 17

User Space和Kernel
Space是操作系统一编写程中常用的定义,表示方今的代码在用户空间依旧基本空间运维,对于不相同的运营空间,CPU对内存的处理方式稍有不相同,在讲进度虚拟地址空间时再涉及该概念。

系统调用指操作系统内核提供的功力,它提供了接口给用户空间代码调用。比如open/read/write/close等,都是属于Linux系统操作接口,而fopen/fread/fwrite/fclose是属于C标准提供的接口,在Linux下,fopen其实底层调用了open。

布署文件:
/etc/profile:系统运转时被实施
~/.bashrc:用户登陆时会调用

1.七 错误处理

系统调用在相似情状下重临整数,并且0表示成功,小于0表示战败。当系统调用再次回到战败时,能够透过errno得到错误嘛,通过strerror获取错误演说,可能直接通过perror在正规错误文件中,输出错误新闻。

 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
// 通过open重回的平头,在linux中有个尤其的名字
// 叫文件讲述符 file description 简称fd

int fd = open(“a.txt”, O_WRONLY|O_CREAT|O_EXCL, 0777);
if(fd < 0)//表示文件打开退步
{
perror(“open”);
return 0;
}

// 把指针放到文件开头
lseek(fd, 0, SEEK_SET);

// 对文本实行操作
write(fd, “hello”, 5);

// 关闭文件,要是不倒闭,内部存款和储蓄器会泄漏
// 当进度退出时,未关门的公文仲活动关闭
close(fd);

}

1.拾 系统调用和库函数

学学Linux系统开发接口时,程序员也必要学习1般常用的第三方库,来进行程序员的编制程序能力。

 

home88一必发 18

User Space和Kernel
Space是操作系统一编写程中常用的定义,表示如今的代码在用户空间依旧基本空间运转,对于不一致的运行空间,CPU对内部存款和储蓄器的处理情势稍有分裂,在讲进程虚拟地址空间时再涉及该概念。

系统调用指操作系统内核提供的功用,它提供了接口给用户空间代码调用。比如open/read/write/close等,都以属于Linux系统操作接口,而fopen/fread/fwrite/fclose是属于C标准提供的接口,在Linux下,fopen其实底层调用了open。

布署文件:
/etc/profile:系统运维时被实施
~/.bashrc:用户登陆时会调用

7.7.2 锁(临界量)

锁能防止五个线程同时做客3个全局变量。
锁会拉动四个难题:

  • 效率低

  • 死锁

    #include <stdio.h>
    #include <pthread.h>
    
    int result = 0;
    // 定义锁,锁一般也定义在全局
    //pthread_mutex_t mutex;  // 粗粒度的锁
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    int result1 = 0;
    pthread_mutex_t mutex1;
    
    // 1.一个线程重复加锁两次,会死锁
    void func()
    {
        pthread_mutex_lock(&mutex);
    
        pthread_mutex_unlock(&mutex);
    }
    
    void foo()
    {
        pthread_mutex_lock(&mutex);
        func();
        pthread_mutex_unlock(&mutex);
    }
    
    // 2. 一个线程加锁之后,忘记了解锁
    void foo1()
    {
    
        pthread_mutex_lock(&mutex);
        if(...) // 这种场合容易产生忘记解锁
            return;
        // ....
        // 忘记了解锁
        pthread_mutex_unlock(&mutex);
    }
    
    void foo2()
    {
        // 因为别的线程忘记解锁,所以本线程无法进行加锁
        pthread_mutex_lock(&mutex); // 阻塞在这里
        pthread_mutex_unlock(&mutex);
    }
    
    void* thread_func(void* ptr)
    {
        foo();
    
        int i=0;
        for(i=0; i<100000; ++i)
        {
            pthread_mutex_lock(&mutex1);
            result1++;//它的值由什么决定
            pthread_mutex_unlock(&mutex1);
    
            // 两个线程同时操作全局变量,结果不可靠
            //
            // 将该操作变成原子操作,或者至少不应该被能影响它操作的人打断
            pthread_mutex_lock(&mutex);
            result ++;  // result++代码被锁保护了,不会被其他线程的result++影响
            pthread_mutex_unlock(&mutex);
        }
        return NULL;
    }
    
    int main()
    {
        // 使用锁之前,要对它进行初始化
    //    pthread_mutex_init(&mutex, NULL);
        pthread_mutex_init(&mutex1, NULL);
    
        pthread_t t1, t2;
        pthread_create(&t1, NULL, thread_func, NULL);
        pthread_create(&t2, NULL, thread_func, NULL);
    
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
    
        printf("result is %d\n", result);
    }
    
    #include <stdio.h>
    #include <list>
    #include <iostream>
    using namespace std;
    
    struct task_t
    {
        int task;
    };
    
    // 全局的任务队列
    list<task_t*> tasks;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    
    // pthred_cond_signal和pthread_cond_wait类似不可靠信号,signal不会累计
    // 当一个线程发送signal时,如果另外一个线程此时没有调用wait函数,那么这个signal就会消失掉

    void* work_thread(void* ptr)
    {
        while(1)
        {
            // 等待条件
            pthread_mutex_lock(&mutex);
            pthread_cond_wait(&cond, &mutex);
            pthread_mutex_unlock(&mutex);

            // 一旦条件满足,就应该处理队列中所有的任务
            while(1)
            {
                pthread_mutex_lock(&mutex);
                if(tasks.size() == 0) 
                {
                    pthread_mutex_unlock(&mutex); // 特别容易忘记解锁
                    break;
                }
                task_t* task = *tasks.begin();
                tasks.pop_front();
                pthread_mutex_unlock(&mutex);

                // 处理任务
                printf("current task is %d\n", task->task);

                // new和delete(malloc和free)都是线程安全的
                delete task;
            }
        }
    }

    int main()
    {
        pthread_mutex_init(&mutex, NULL);
        pthread_cond_init(&cond, NULL);

        pthread_t tid;
        pthread_create(&tid, NULL, work_thread, NULL);

        while(1)
        {
            int i;
            // 阻塞的,等待任务
            cin >> i;

            // 构造任务结构体
            task_t* task = new task_t;
            task->task = i;

            // 把任务丢到任务列表中
            pthread_mutex_lock(&mutex);
            tasks.push_back(task);
            pthread_mutex_unlock(&mutex);

            // 唤醒条件变量
            pthread_cond_signal(&cond);
        }
    }

    //运用析构函数

    #ifndef __AUTO_LOCK_H__
    #define __AUTO_LOCK_H__

    #include <pthread.h>

    class auto_lock
    {
    public:
        auto_lock(pthread_mutex_t& m);
        ~auto_lock();
    private:
        pthread_mutex_t& mutex;
    };

    #endif



    #include "auto_lock.h"

    auto_lock::auto_lock(pthread_mutex_t& m): mutex(m)
    {
        pthread_mutex_lock(&mutex);
    }

    auto_lock::~auto_lock()
    {
        pthread_mutex_unlock(&mutex);
    }



    #include <stdio.h>
    #include "auto_lock.h"

    pthread_mutex_t mutex;
    int result = 0;

    void* thread_func(void*ptr)
    {
        for(int i=0 ;i<100000; ++i)
        {
            auto_lock var1(mutex); // 重复加锁
            auto_lock var(mutex); // 在构造里自动加锁
            result++;
        }
    }

    int main()
    {
        // 变成递归锁   及循环锁  
        pthread_mutexattr_t attr;//设计循环锁属性
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 

        // 用递归属性去初始化这个锁
        pthread_mutex_init(&mutex, &attr);

        pthread_t tid1, tid2;
        pthread_create(&tid1, NULL, thread_func, NULL);
        pthread_create(&tid2, NULL, thread_func, NULL);

        pthread_join(tid1, NULL);
        pthread_join(tid2, NULL);

        printf("result is %d\n", result);
    }

 

相对的化解措施:

  • 读写锁

  • #include

    pthread_rwlock_t mutex;
    int result;
    
    void* thread_func(void* ptr)
    {
        pthread_rwlock_rdlock(&mutex);
        // 只能对数据读
        result ++; // 写数据的行为是会导致数据不正确
        pthread_rwlock_unlock(&mutex);
    
        pthread_rwlock_wrlock(&mutex);
        // 可以对数据读写
        pthread_rwlock_unlock(&mutex);
    }
    
    int main()
    {
    
        pthread_rwlock_init(&mutex, NULL);
    
        pthread_t tid;
        pthread_create(&tid, NULL, thread_func, NULL);
    }
    

     

  • 循环锁

文件操作

头文件:sys/types.h  sys/stat.h
 fcntl.h  例:int fd=open(“文件路径”,mode);
 mode决定了对文本的操作方式  第伍个参数可有可无,对文本权限进行处理,   因umask存在,创立文件权限要与上000 000 0十的反,导致用户权限起先不能够有写的权杖

mode选项

解释

O_RDONLY

读方式打开(与后面俩个互斥)

O_WRONLY

写方式打开

O_RDWR

读写方式打开

O_CREAT

创建文件,如果文件存在,直接打开

O_TRUNC

截断

O_APPEND

追加

O_EXCL

和O_CREAT一起用,如果文件存在则失败

壹.八 用户、组、文件权限

Linux是多用户系统,扶助八个用户同时登6系统。
为了安全起见,必要对系统的权能加于规范。

文本操作

头文件:sys/types.h  sys/stat.h
 fcntl.h  例:int fd=open(“文件路径”,mode);
 mode决定了对文本的操作方法
  第七个参数可有可无,对文件权限实行拍卖,   因umask存在,创制文件权限要与上000 000 010的反,导致用户权限开端不能够有写的权柄

mode选项

解释

O_RDONLY

读方式打开(与后面俩个互斥)

O_WRONLY

写方式打开

O_RDWR

读写方式打开

O_CREAT

创建文件,如果文件存在,直接打开

O_TRUNC

截断

O_APPEND

追加

O_EXCL

和O_CREAT一起用,如果文件存在则失败

7.7.2.1 基本锁

类型:pthread_mutex_t
概念的变量1般在全局:pthread_mutex_t g_mutex;
在动用在此以前要开端化:pthread_mutex_init(&g_mutex, NULL);
做客敏感目的前加锁:pthread_mutex_lock(&g_mutex);
走访结束要解锁:pthread_mutex_unlock(&g_mutex);

1把所可以负担多个全局变量的新余题材,不过担负的界定越大,作用越低,代码绝对不难写。负责全局变量的数码,被称之为锁的粒度。

死锁难点

  1. 忘掌握锁会时有产生死锁

  2. 双重加锁会促成死锁

怎么消除死锁难点:

  1. 忘明白锁:程序员自身要注意

  2. 双重加锁:使用循环锁可以消除难题

函数:

perror:对某种错误音讯实行打字与印刷

open/creat:打开文件/成立文件
read:读文件
write:写文件
close:关闭文件
lseek:定位文件读写地方
fcntl:修改文件属性
sysconf:读取系统布局
dup/dup二:复制文件讲述符
sync/fsync/fsyncdata:同步文件数量
mmap/munmap:文件映射
mkstemp:获得近年来文件路径

1.9 信号

实信号是经过通讯的一种手段,某些进度收到信号,该实信号也许出自内核、来自其余进度恐怕来自用户操作。例如:当用户按下ctrl+c时,其实是给前台进度发送了贰个非时限信号。

函数:

perror:对某种错误新闻进行打印

open/creat:打开文件/创设文件
read:读文件
write:写文件
close:关闭文件
lseek:定位文件读写地方
fcntl:修改文件属性
sysconf:读取系统布置
dup/dup二:复制文件讲述符
sync/fsync/fsyncdata:同步文件数量
mmap/munmap:文件映射
mkstemp:得到近年来文件路径

7.7.2.2 循环锁

消除重复加锁导致死锁难点,循环锁的天性是,同2个线程实行频仍加锁,不会卡住。
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&mutex); //
第2遍加锁不会卡住,可是它会给mutex扩大3个计数。
pthread_mutex_unlock(&mutex) // 收缩计数
pthread_mutex_unlock(&mutex);//减弱到0的时候,真正解锁

怎么设置循环锁。

     pthread_mutexattr_t attr;

     // 设置成循环锁属性

     pthread_mutexattr_init(&attr);

     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

 

     // 此时mutex是二个循环锁

     pthread_mutex_init(&mutex, &attr);

 

//头文件
#ifndef __AUTO_LOCK_H__
#define __AUTO_LOCK_H__

#include <pthread.h>

class auto_lock
{
public:
auto_lock(pthread_mutex_t& m);
~auto_lock();
private:
pthread_mutex_t& mutex;
};

#endif

//头文件的实现

#include “auto_lock.h”

auto_lock::auto_lock(pthread_mutex_t& m): mutex(m)
{
pthread_mutex_lock(&mutex);
}

auto_lock::~auto_lock()
{
pthread_mutex_unlock(&mutex);
}

//主函数
#include <stdio.h>
#include "auto_lock.h"

pthread_mutex_t mutex;
int result = 0;

void* thread_func(void*ptr)
{
    for(int i=0 ;i<100000; ++i)
    {
        auto_lock var1(mutex); // 重复加锁
        auto_lock var(mutex); // 在构造里自动加锁
        result++;
    }
}

int main()
{
    // 变成递归锁
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 

    // 用递归属性去初始化这个锁
    pthread_mutex_init(&mutex, &attr);

    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, thread_func, NULL);
    pthread_create(&tid2, NULL, thread_func, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    printf("result is %d\n", result);
}

 

命令

touch:修改文件的拜会时间,创制文件
cat:访问文件内容
vim:编辑
ulimit:展现一些限量音讯(文件讲述符最大值、栈的长空尺寸)
umask:文件创制的权限掩码
getconf:对应sysconf

dd:能够拷贝块设备,可是要sudo权限  例  dd if=地点 of=文件名  bs=3回多少k cout=拷贝次数

Wc:计算文件的行数  单词个数
字节数

unlink:删除软链接

 

壹.10 系统调用和库函数

学学Linux系统开发接口时,程序员也急需学习1般常用的第一方库,来拓展程序员的编制程序能力。

  home88一必发 19

User Space和Kernel
Space是操作系统一编写程中常用的定义,表示近年来的代码在用户空间照旧基本空间运转,对于分裂的运营空间,CPU对内部存储器的处理方式稍有不一样,在讲进度虚拟地址空间时再涉及该概念。

系统调用指操作系统内核提供的功用,它提供了接口给用户空间代码调用。比如open/read/write/close等,都以属于Linux系统操作接口,而fopen/fread/fwrite/fclose是属于C标准提供的接口,在Linux下,fopen其实底层调用了open。

布局文件:
/etc/profile:系统运营时被执行
~/.bashrc:用户登6时会调用

命令

touch:修改文件的访问时间,制造文件
cat:访问文件内容
vim:编辑
ulimit:显示1些限制新闻(文件讲述符最大值、栈的空中尺寸)
umask:文件创造的权限掩码
getconf:对应sysconf

dd:能够拷贝块设备,不过要sudo权限  例  dd if=地方 of=文件名  bs=1次多少k cout=拷贝次数

Wc:总结文件的行数  单词个数
字节数

unlink:删除软链接

 

七.7.2.3 读共享写排他锁(读写锁)

共享锁/排他锁
定义锁:pthread_rwlock_t mutex;
初始化:pthread_rwlock_init(&mutex, NULL);
读锁定:pthread_rwlock_rdlock(&mutex);
写锁定:pthread_rwlock_wrlock(&mutex);
解锁:pthread_rwlock_unlock(&mutex);

信号

是控制进程通讯的1种方法,成效高,成本低

频域信号处理情势:掩盖、忽略、暗中同意处理

掩码:延迟复信号的处理  运用功率信号集合   

蒙面离谱赖复信号,多次出殡和埋葬,只处理一回  掩盖:可信赖能量信号  处理多次

进程

fork()创建

文本操作

头文件:sys/types.h  sys/stat.h  fcntl.h  例:int
fd=open(“文件路径”,mode);  mode决定了对文件的操作方式  第多少个参数可有可无,对文本权限举行拍卖,
  因umask存在,创制文件权限要与上000 000
0十的反,导致用户权限初阶不可能有写的权能

mode选项

解释

O_RDONLY

读方式打开(与后面俩个互斥)

O_WRONLY

写方式打开

O_RDWR

读写方式打开

O_CREAT

创建文件,如果文件存在,直接打开

O_TRUNC

截断

O_APPEND

追加

O_EXCL

和O_CREAT一起用,如果文件存在则失败

信号

是控制进度通讯的1种格局,效能高,花费低

复信号处理形式:掩盖、忽略、暗中认可处理

掩码:延迟功率信号的拍卖  运用复信号集合   

蒙面不可信赖实信号,数十一次发送,只处理一回  掩盖:可相信非信号  处理多次

进程

fork()创建

7.7.2.4 总结

  1. 任由什么锁,都会造成质量下跌,所以能不用就尽量不用

  2. 锁能否用于进度间共同?能够

线程

鼠标键盘都以只读的字符文件夹设备,所以能够运用函数实行监察
 一般在/dev/input/mic 文件下边  注意权限难题 鼠标键盘读取数据,是俩个过程,注意进度的围堵问题 能够选拔字进度和父进度进行处理

函数:

perror:对某种错误音信进行打字与印刷

open/creat:打开文件/创制文件
read:读文件
write:写文件
close:关闭文件
lseek:定位文件读写地点
fcntl:修改文件属性
sysconf:读取系统布置
dup/dup贰:复制文件讲述符
sync/fsync/fsyncdata:同步文件数量
mmap/munmap:文件映射
mkstemp:得到临时文件路径

线程

鼠标键盘都以只读的字符文件夹设备,所以能够选取函数进行监督
 一般在/dev/input/mic 文件下边  注意权限问题 鼠标键盘读取数据,是俩个经过,注意进度的封堵难题 能够利用字进度和父进度进行处理

 C++使用构造函数和析构函数自动加锁解锁

线程的创办 

 pthread_created(一,2,三,4)
//1:线程的id  贰:线程的的性质  三:新线程的函数名字, 4:新线程的个性    要链接  -lpthread  库   

只顾子线程是隶属主线程的,主线程甘休,子线程无法运维    
这么些 pthread_exit(0)主线程甘休,子线程没有脱离例外

 

运用pthread_equal  判断线程是还是不是等于,先等再次回到0  不等于重临非零值

pthread_jion(一,&ret)  阻塞调用 1:线程id  ret:线程重临值

 

pthread_t tid = pthread_self()  获得当前运营进程的id

命令

touch:修改文件的访问时间,成立文件
cat:访问文件内容
vim:编辑
ulimit:突显1些范围消息(文件讲述符最大值、栈的空中尺寸)
umask:文件创立的权能掩码
getconf:对应sysconf

dd:能够拷贝块设备,不过要sudo权限  例  dd if=位置 of=文件名
 bs=一遍多少k cout=拷贝次数

Wc:总括文件的行数  单词个数 字节数

unlink:删除软链接

 

线程的开创 

 pthread_created(1,二,3,四)
//一:线程的id  二:线程的的性格  三:新线程的函数名字, 4:新线程的属性    要链接  -lpthread  库   

留意子线程是专属主线程的,主线程甘休,子线程不可能运维    
这些 pthread_exit(0)主线程甘休,子线程未有退出例外

 

运用pthread_equal  判断线程是或不是等于,先等重回0  不对等重返非零值

pthread_jion(一,&ret)  阻塞调用 一:线程id  ret:线程重返值

 

pthread_t tid = pthread_self()  获得当前运作进程的id

7.七.3 条件变量

规则变量是别的1种共同机制,它能够使线程在无竞争的等候条件发生。在前头讲到的线程场景里,子线程往往要等到队列有数据才运营,不然它应有休眠,以幸免浪费CPU。然则倘若用锁来达成那种体制以来,会越发麻烦。

定义:pthread_cond_t g_cond;
初始化:pthread_cond_init(&g_cond);
等待:pthread_cond_wait(&g_cond, &g_mutex);
唤醒:pthread_cond_signal(&g_cond);
pthread_cond_broadcast(&g_cond);
惊群

#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex;
pthread_cond_t cond;

void* thread_func(void* ptr)
{
    sleep(1);

    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&cond, &mutex);
    pthread_mutex_unlock(&mutex);

    printf("wait ok\n");
}

int main()
{
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);

    // 发信号时,线程不是正在调用pthread_cond_wait,而是在执行sleep(1),所以signal发送之后,就消失了,不会保留
    // 按照刚才的说法,这个signal根本无效
    // 所以当一个线程发送多次的signal时,那么最多只有一次是有作用的
    pthread_cond_signal(&cond);

    pthread_join(tid, NULL);

}

 

进程和线程的区分:

经过:分配财富的单位  线程:调度的单位     拾2线程能够共享全局变量

信号

是决定过程通信的一种格局,效用高,开销低

时域信号处理格局:掩盖、忽略、暗许处理

掩码:延迟频域信号的拍卖  运用时限信号集合   

覆盖不可靠赖频限信号,多次发送,只处理一遍   掩盖:可信赖复信号  处理数十次

进程

fork()创建

进程和线程的分别:

经过:分配财富的单位  线程:调度的单位     多线程能够共享全局变量

七.七.三.① 条件变量的等候和唤醒

设若未有线程在等待条件,此时唤醒函数pthread_cond_signal不会唤起任何的线程,也不会记录。

假使有八个线程在履行pthread_cond_wait,而此时有一个线程调用pthread_cond_signal,那么只会唤醒当中2个线程。

若果想提示全数线程,那么调用pthread_cond_broadcast,该函数能够提醒等待该原则的具备线程。

#include <stdio.h>
#include <pthread.h>

// 假如有三个线程同时调用pthread_cond_wait,一个线程调用pthread_cond_signal
//
pthread_mutex_t mutex;
pthread_cond_t cond;

void* thread_func(void* ptr)
{

    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&cond, &mutex);
    pthread_mutex_unlock(&mutex);

    printf("wait ok\n");
}

int main()
{
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_t tid1, tid2, tid3;
    pthread_create(&tid1, NULL, thread_func, NULL);
    pthread_create(&tid2, NULL, thread_func, NULL);
    pthread_create(&tid3, NULL, thread_func, NULL);

    sleep(1);
    // 唤醒一个线程
//    pthread_cond_signal(&cond);
//    唤醒所有正在等待的线程
    pthread_cond_broadcast(&cond);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);

}

 

幸免俩个线程同时操作全局变量,第二个线程运用了锁,前面的线程在外场等,等待解锁后,后边的线程在进入

线程

鼠标键盘都以只读的字符文件夹设备,所以能够使用函数实行监察
 一般在/dev/input/mic 文件上面  注意权限难题 鼠标键盘读取数据,是俩个进度,注意进度的堵塞难点 可以选择字进度和父进度举行处理

防止俩个线程同时操作全局变量,第二个线程运用了锁,后边的线程在外场等,等待解锁后,前边的线程在进入

7.7.4 信号量

时限信号量类似条件变量,但是随机信号量能够保存时域信号数量。

  • 定义: sem_t sem;

  • 初始化:sem_init(&sem, 0, 0);
    初步化的首个参数,倘使是0表示无差异进度内的多线程之间的时域信号量,假设是非0,那么该非时限信号量能够应用在经过之间。第陆个参数表示频域信号量的发轫值。

  • 等待:sem_wait(&sem);
    sem_wait函数会招致该线程休眠,唤醒的规则是sem的值大于0。并且sem_wait调用截至后,会活动将sem值减壹。

  • 唤醒:sem_post(&sem);
    sem_post只是简单的将sem值+一

    #include <stdio.h>
    #include <semaphore.h>
    #include <pthread.h>
    
    sem_t sem;
    
    void* thread_func(void* ptr)
    {
        sleep(1);
        sem_wait(&sem);
        printf("wait ok\n");
    }
    
    int main()
    {
        sem_init(&sem, 0, 0);
    
        pthread_t tid1, tid2, tid3;
        pthread_create(&tid1, NULL, thread_func, NULL);
        pthread_create(&tid2, NULL, thread_func, NULL);
        pthread_create(&tid3, NULL, thread_func, NULL);
    
        // 发送信号
        sem_post(&sem);
    
        pthread_join(tid1, NULL);
        pthread_join(tid2, NULL);
        pthread_join(tid3, NULL);
    }
    

     

死锁

老是俩次加锁,加锁后,没有解锁,又一连加锁,会促成死锁。
运用循环锁,能够另行加锁   通过定义锁的习性,变为循环锁
 例:pthread_mutexattr_t attr;  pthread_mutexattr_init(&attr);
 pthread_mutexattr_settype(&attr,
PTHREAD_MUTEX_RECURSIVE);pthread_mutex_init(&mutex,&attr)

加锁后,忘记解锁,也会见世死锁
 C++中运用析构函数,能够制止忘记解锁,定义3个类

 

线程的开创 

 pthread_created(1,贰,叁,四) //壹:线程的id  贰:线程的的属性
 3:新线程的函数名字, 四:新线程的品质    要链接  -lpthread  库   

只顾子线程是专属主线程的,主线程结束,子线程不或者运维    
那么些 pthread_exit(0)主线程截至,子线程未有退出例外

 

运用pthread_equal  判断线程是或不是等于,先等重返0  不对等重临非零值

pthread_jion(1,&ret)  阻塞调用 一:线程id  ret:线程重临值

 

pthread_t tid = pthread_self()  获得当前运作进度的id

死锁

连接俩次加锁,加锁后,未有解锁,又连续加锁,会导致死锁。
运用循环锁,能够再一次加锁   通过定义锁的性质,变为循环锁
 例:pthread_mutexattr_t attr;  pthread_mutexattr_init(&attr);
 pthread_mutexattr_settype(&attr,
PTHREAD_MUTEX_RECURSIVE);pthread_mutex_init(&mutex,&attr)

加锁后,忘记解锁,也会并发死锁
 C++中央银行使析构函数,能够制止忘记解锁,定义一个类

 

7.8 重入

只要函数操作了全局变量,这么些函数就不是可重入的函数了。

#include <stdio.h>
#include <pthread.h>
#include <string.h>
int result = 0;
void foo()
{
    // 因为这个函数操作了全局变量
    result ++;
}

void* thread_func(void* ptr)
{
#if 0
    int i;
    for(i=0; i<10000; ++i)
    {
        // 该函数是不可重入的函数
        // 用锁来保护它
        foo();
    }
#endif

    char p[] = "1 2 3 4 5 6 7 8 9 0";

    char* saveptr;
    char* sub = strtok_r(p, " ", &saveptr);
    while(sub)
    {
        usleep(1000); // 1毫秒        
        printf("%s, tid=%d\n", sub, (int)pthread_self());
        sub = strtok_r(NULL, " ", &saveptr);
    }

}

int main()
{
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, thread_func, NULL);
    pthread_create(&tid2, NULL, thread_func, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    printf("result=%d\n", result);
}

 

读写锁

pthread_rwlock_t mutex;

pthread_rwlock_init(&mutex, NULL);

读/写锁定pthread_rwlock_rd/wrlock(&mutex);

解锁:pthread_rwlock_unlock(&mutex);

进度和线程的界别:

进程:分配能源的单位  线程:调度的单位     八线程可以共享全局变量

读写锁

pthread_rwlock_t mutex;

pthread_rwlock_init(&mutex, NULL);

读/写锁定pthread_rwlock_rd/wrlock(&mutex);

解锁:pthread_rwlock_unlock(&mutex);

7.9 分离的线程

分离的线程不用pthread_join,也无力回天通过pthread_join来取得结果。因为它运转结束之后,它的PCB同时被假释了。

#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <inttypes.h>

// intptr_t 整数类型:char short int long (long long)
//     整数:8 16 32 64
//     有些机器的int是32位,有的机器是64位
//     void*指针类型都是按照机器的字长决定
//
//     intptr_t是一个整数,并且它总是和指针的字节数是一样的

void* thread_func(void* ptr)
{
    // 用的是地址本身,而不是地址指向的值
    printf("%d\n", (int)(intptr_t)ptr);
    sleep(1);
}

int foo()
{
    char p[] = "hello world";
    int a = 100;

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    pthread_t tid;
    pthread_create(&tid, &attr, thread_func, (void*)(intptr_t)a);

    // 该线程自生自灭
    // pthread_detach(tid);

    int ret = pthread_join(tid, NULL);
    printf("join error, ret=%d, errno=%d, EINVAL=%d\n", ret, errno, EINVAL);
}

int main()
{
    foo();
    sleep(2);
}

 

 

防止俩个线程同时操作全局变量,第2个线程运用了锁,前面包车型客车线程在外场等,等待解锁后,前边的线程在进入

 

柒.十 线程私有数量

线程能够定义私有数据,私有数据只供该线程使用。
线程私有数据能够在该线程调用函数中访问,别的线程调用的函数中,不可访问。

// 定义线程私有多少的key,是在线程设置和应用民用数据在此之前成立

pthread_key_t key;

pthread_key_create(&key, 用来清理私有多少的函数指针);

 

// 设置私有多少,该函数被特别线程调用,那么正是安装该线程私有数量

pthread_set_specific(key, data);

void* data = pthread_get_specific(key);

 

#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

pthread_key_t key;

// 可能被线程A调用
// 也可能线程B调用
void foo()
{
    char* p = (char*)pthread_getspecific(key);
    printf("%s\n", p);
}

void my_malloc()
{
    // 去这个线程的内存池去申请内存
    void* mempool = pthread_getspecific(key);
  //  __my_malloc(mempool, ...);
}

void* thread_func(void* ptr)
{
    // setspecific,需要在线程中调用,当然也可以在主线程中调用
    // 为这个线程设置私有数据
    pthread_setspecific(key, ptr);

    foo();
    my_malloc();
    return NULL;
}

void free_func(void* ptr)
{
    printf("free call\n");
    free(ptr);
}

int main()
{
    pthread_key_create(&key, free_func);

    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, thread_func, strdup("thread1"));
    pthread_create(&tid2, NULL, thread_func, strdup("thread2"));

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

}

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

// 线程本地变量,每个线程都有一份拷贝
thread_local int result = 0;

void foo()
{
    // 全局变量
    thread_local static int a = 0;
    a++;
    printf("%d\n", a);
}



void* thread_func1(void* ptr)
{
    foo();
    foo();
    result = 100;
}

void* thread_func2(void* ptr)
{
    foo();
    foo();

    sleep(1);
//    printf("%d\n", result); // 100
    printf("%d\n", result); // thread_local时,这个值是0
}

int main()
{
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, thread_func1, NULL);
    pthread_create(&tid2, NULL, thread_func2, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
}

 

守护进度

护理进度不和终极关联,注意此过程只可以有贰个,创造文件记录,判断此程序是还是不是开启

死锁

连接俩次加锁,加锁后,未有解锁,又延续加锁,会导致死锁。
运用循环锁,能够再度加锁   通过定义锁的性质,变为循环锁
 例:pthread_mutexattr_t attr;  pthread_mutexattr_init(&attr);
 pthread_mutexattr_settype(&attr,
PTHREAD_MUTEX_RECURSIVE);pthread_mutex_init(&mutex,&attr)

加锁后,忘记解锁,也会现出死锁
 C++中应用析构函数,能够制止忘记解锁,定义三个类

 

护理进程

守护进度不和顶峰关联,注意此进度只可以有三个,创立文件记录,判断此程序是还是不是打开

柒.1一 线程撤除

裁撤线程也截止线程,可是应当防止那种规划。

脱离点函数:man pthreads搜索cancel关键字,找到那么些退出点函数。

pthread_cancel在线程外部(别的线程)来退出另外3个线程A,当线程A调用了cancelpoint函数时,会退出。

比方指望调用cancelpoint函数不脱离,应该设置当前的线程状态为:不理睬线程退出(cancelability
disabled)
pthread_setcancelstate(…)

#include <stdio.h>
#include <pthread.h>

void* thread_func(void* ptr)
{
    // 因为这个线程没有cancel point
    while(1)
    {
        // 关闭cancel检测
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

        sleep(10);

        // 打开cancel检测
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

        // 检查cancel point
        pthread_testcancel(); 
    }
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);

    // 让线程退出
    pthread_cancel(tid);

    // 等待线程退出
    pthread_join(tid, NULL);
}

 

编程规则:

设umask=0;

调用fork,让父进程退出。    让父进程变为init,  如若父进度不脱离,用俩次fork()

调用setuid创立新会话  setsid

重设当前目录/根目录     chdir        

关闭不必要的公文讲述符    运用循环关闭全体文件讲述符

读写锁

pthread_rwlock_t mutex;

pthread_rwlock_init(&mutex, NULL);

读/写锁定pthread_rwlock_rd/wrlock(&mutex);

解锁:pthread_rwlock_unlock(&mutex);

编制程序规则:

设umask=0;

调用fork,让父过程退出。    让父进度变为init,  即使父进程不脱离,用俩次fork()

调用setuid创立新会话  setsid

重设当前目录/根目录     chdir        

闭馆不必要的文书讲述符    运用循环关闭全数文件讲述符

高级IO

一个进程正是一段指令

 

高级IO

一个历程正是一段指令

IO复用技术

守护过程

护理进度不和终极关联,注意此进度只可以有一个,成立文件记录,判断此程序是不是打开

IO复用技术

select的运用

行使文件讲述符集合  运用fd_set成立文件讲述符集合
 文件接口相对较小,跨平台利用

FD_SET(1,2)
将文件讲述符放入文件讲述符集合  一:文件讲述符  2:集合名字

编制程序规则:

设umask=0;

调用fork,让父进度退出。    让父进度变为init,
 如若父进度不脱离,用俩次fork()

调用setuid创立新会话  setsid

重设当前目录/根目录     chdir        

关门不需求的公文讲述符    运用循环关闭全部文件讲述符

select的运用

动用文件讲述符集合  运用fd_set创造文件讲述符集合
 文件接口相对较小,跨平台选取

FD_SET(1,贰)
将文件讲述符放入文件讲述符集合  1:文件讲述符  二:集合名字

epoll的运用

epollfd  创立文件讲述符集合

epol_ctl将文件讲述参预集合中

高级IO

四个进度就是一段指令

epoll的运用

epollfd  创建文件讲述符集合

epol_ctl将文件讲述参预集合中

非阻塞IO

 

IO复用技术

非阻塞IO

 

管道

一边读,一边写

select的运用

运用文件讲述符集合  运用fd_set创立文件讲述符集合
 文件接口相对较小,跨平台应用

FD_SET(1,二) 将文件讲述符放入文件讲述符集合  1:文件讲述符
 2:集合名字

管道

一边读,一边写

匿名管道  pipe()创设管道

 

 

mmap  能够兑现有亲子关系进度的文本共享
 功能低,数据写入内部存款和储蓄器,在从内部存款和储蓄器中读取数据
 运用shm_open完结文件共享也得以

文本内部存款和储蓄器共享,极小概展开通信

 

经过锁,让进程共享内部存款和储蓄器举办通信 pthread_mutex_init  要求将锁放在共享内部存款和储蓄器中  

 

fork  +  exec 让进度有例外的功力

 

epoll的运用

epollfd  制造文件讲述符集合

epol_ctl将文件讲述参加集合中

匿名管道  pipe()创制管道

 

 

mmap  能够实现有亲子关系进度的文件共享
 功效低,数据写入内部存款和储蓄器,在从内部存款和储蓄器中读取数据
 运用shm_open完毕文件共享也可以

文本内存共享,不能开始展览通讯

 

通过锁,让进程共享内部存款和储蓄器进行通信 pthread_mutex_init  须求将锁放在共享内部存款和储蓄器中  

 

fork  +  exec 让进度有分化的意义

 

非阻塞IO

 

管道

一边读,一边写

匿名管道  pipe()创设管道

 

 

mmap  能够完成有亲子关系进度的公文共享
 成效低,数据写入内存,在从内部存款和储蓄器中读取数据
 运用shm_open完成文件共享也可以

文件内部存款和储蓄器共享,不恐怕进行通讯

 

透过锁,让进程共享内部存款和储蓄器举行通讯  pthread_mutex_init
 须要将锁放在共享内部存款和储蓄器中  

 

fork  +  exec 让进程有两样的功能

 

概述,linux第2章概述 第二章 概述
一.一 前言
本章商讨系统的定义,从硬件、操作系统角度更是深刻的敞亮计算机连串,并快…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图