2021-4-30学习记录

主题:

日常练习系列。包括:

  • 进程和线程(linux常用命令)
  • 进程状态(linux平台)
  • 系统IPC
  • 实现消息队列通信代码(cpp)

代码:

#include <stdio.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h> //fork函数
#include <sys/ipc.h>
#include <cstring>
#include <sys/msg.h> //里买你有消息的发送函数

using namespace std;

class Message  //消息的类别,必须有一个type
{
    public:
    Message(long t, char* s)
    {
        type = t;
        strcpy(message, s);
    }
    Message()
    {

    }
    long type;
    char message[100];
};

int main()
{
//----------------进程和线程------------------------------
//  进程之间的派生过程是一个 fork and exec的过程。也就是先调用一个fork,创造一个和他自己
//一样的进程,新的进策有一个pid和ppid,ppid就是上一个进程的pid。然后以exec的方式来加载
//实际要执行的程序。
//  进程中会有一些父进程派生的子进程,如果只是杀掉子进程,那么父进程还会创造子进程。
//pid也会是一样的。有一些进程是常驻内存的。常驻内存的进程可以认为是 服务。
//  在linux下使用ps可以静态查看进程,top动态查看进程,pstree可以查看进成树。
//ps aux可以查看所有进程状态。ps -l 可以查看当前bash下的所有子进程。
//ps -lA可以查看所欲进程状态,格式和aux不一样。
//  在一个bash进程中可以同时完成多个工作,这是设计到工作管理(job control)。最简单
//的做法是在一个命令后面加上&,可以将这个进程 扔到背景中 。放到背景的进程不会被
//ctrl c终止。也就是在后台执行。但是仅仅这样的话,进程导致的标准输入输出,
//仍然会出现在屏幕上。所以可以用 数据流重导向 而就是>这个运算符。可以将一个文件
//的标准输出导向到另外一个文件中。在这里有0:标准输入  1:标准输出 2:标准错误输出
//使用&来修饰的话,就可以认为是一个文件描述符。>的前面必须是一个流,一个命令代表的其实
//是标准输出。>的后面必须是一个文件描述符,也就是代表一个文件。因此要想将2重定向到1的话
//必须用2>&1;  ctrl z可以把一个进程放到后台,并且stop的状态。
//当有job在后台运行的时候,可以使用jobs命令来查看后台程序和状态
//用fg可以调到前台执行。bg可以让一个job在后台运行。
//  当想要kill掉一个进程的时候,可以用kill命令。参数-9表示强制终止,只是用于异常的进程
//-l5用于正常终止。后面默认的数字是pid,也可以加用 %job号


//-------------------进程状态----------------------
//  linux中进程的状态有R(运行), S和D都表示被阻塞(S为可以被信号激活,signal,可以kill掉)
//而D表示不会被信号激活,也不会被kill掉(不常见)。T表示stop。Z表示僵尸状态。
//对应于状态图的话,就绪状态非常不常见。阻塞有两种对应状态。
//  僵尸进程的产生:当子进程退出,但是由于子进程的完全推出需要父进程的配合(调用wait)
//但是如果此时,恰好父进程不处于运行状态,比如调用sleep函数(处于S)。那么就会产生僵尸进程。
/*
pid_t pid = fork();
if(pid==0) //子进程
{
    exit(0);
}
else if(pid>0){  //父进程
    sleep(60);  //休眠1分钟,处于S状态
}
*/

//----------------系统IPC------------------
//包括消息队列,信号量(semaphore),信号(signal),共享内存(以来信号量机制来完成同步)
//套接子通信(socket)
//  消息队列:消息队列是信息的链表,存放与内核当中。消息面向记录,消息具有特定的格式以及特定
//的优先级。消息和有名管道类似,不依赖于具体进程。不随着特定进程的退出来销毁。
//消息队列有一个id来进行标识,消息可以随机查询,按照类别进行查询。
//  信号量(semaphore)不是存储进程之间的通信数据,而是实现资源的互斥和同步。常常和共享
//内存结合来传递通信信息。依赖操作系统提供的PV原子操作。
//  信号(signal)和信号量是不一样的,而且比较复杂。
//  共享内存:是最快的IPC方式,但是需要配合信号量才可以实现多个进程的同时操作。
//  socket可以实现不同主机之间的通信。socket本质上就是进程之间的通信。在网络中很常见。

//------------消息队列代码实现---------------------
//消息代码可以实现传递多种数据类型的数据流,可以实现异步传输。

key_t key = ftok("/home/xuyangli/", 'x');  //以来于ipc.h和sys/types.h   创建一个key,用来获得消息id
                //参数为一个路径,一个标志,必须用单引号
if(key<0)
{
    perror("create key");
    return 0;
}

int msgid = msgget(key, IPC_CREAT|0666);  //根据key来找到或者创建一个队列,然后返回一个id
                //返回一个id,可以直接指定创建时的权限,flag非常类似open
if(msgid<0)
{
    perror("getid");
    return 0;
}

char m[100] = "hello hello";
Message mess(0, m);
int rs = msgsnd(msgid, &mess, sizeof(mess)-sizeof(long), IPC_NOWAIT);//非阻塞的方式
    //发送函数,消息id,消息类的指针,发送的长度,发送flag(这里表示不阻塞发送)
if(rs<0)
{
    perror("发送:");
    return 0;
}

Message messrcv(0,NULL);
int rv = msgrcv(key, &messrcv, sizeof(messrcv), 0, IPC_NOWAIT );
if(rv<0)
{
    perror("receive");
    return 0;
}

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值