一、UNIX基础知识(3)

UNIX基础知识(2)

四、程序和进程

1.程序

程序即可执行文件。内核使用exec函数,将程序读入内存,并执行程序。

2.进程和进程ID

程序执行的实例称为进程。UNIX系统确保每个进程都有一个唯一的数字标识符,称为进程ID(PID),每个进程都有自己的内存空间、变量和文件句柄等资源。进程之间相互独立,彼此不会直接干扰。操作系统通过为每个进程分配时间片来实现多任务调度,使得多个进程可以并发地执行。进程具有以下特点:

  1. 独立性:每个进程都是独立的实体,拥有自己的内存空间和资源。
  2. 并发性:多个进程可以同时运行,通过操作系统的调度机制实现。
  3. 隔离性:进程之间的内存空间是相互隔离的,一个进程无法直接访问另一个进程的内存。
  4. 通信机制:进程之间可以通过进程间通信(Inter-Process Communication,IPC)机制进行数据交换和协作。
实例
#include "apue.h"

int main(void){
    printf("hello world from process ID %ld\n",(long)getpid());  //程序运行时调用getpid得到进程id
    exit(0);
}

image-20230909202523185

3.进程控制

进程控制是指操作系统对进程的创建、调度、挂起、恢复和终止等操作的管理和控制过程。通过进程控制,操作系统能够有效地管理和调度多个进程,实现多任务并发执行。

#include "apue.h"
#include 

int main(void){
    char buf[MAXLINE];
    pid_t pid;
    int status;

    printf("%% ");
    while(fgets(buf,MAXLINE,stdin)!=NULL){ //从标准输入一次读取一行,存储进入buf数组中
        if(buf[strlen(buf)-1]=='\n'){  //由于输入命令时以换行符终止,因此将换行符替换为null
            buf[strlen(buf)-1]=0;
        }
        if((pid=fork())<0){  //fork创建一个子进程,fork会返回进程ID(非负整数)
            err_sys("fork error");
        }else if(pid==0){  //如果pid当前进程为子进程,则ID=0
            execlp(buf,buf,(char *)0);  //执行命令,第三个参数是一个空指针(char *)0,表示命令行参数列表的结束标志。
            err_ret("couldn't execute: %s",buf); //如果执行失败则调用err_ret函数输出错误信息,并调用exit函数退出子进程
            exit(127);
        }

        if((pid=waitpid(pid,&status,0))<0){ //使用了waitpid函数来等待子进程的终止,并获取子进程的终止状态。waitpid函数的第一个参数是要等待的子进程的进程ID,这里传递的是pid变量。第二个参数是一个整型指针,用于存储子进程的终止状态。在这里,使用&status将终止状态存储到status变量中。第三个参数是一个选项,这里传递了0,表示等待任意子进程的终止。
            err_sys("waitpid error");
        }
        printf("%% ");
    }
    exit(0);
}

一、UNIX基础知识(3)_第1张图片

4.线程和线程ID

线程(Thread)是操作系统中最小的执行单元,是进程中的一个执行流。一个进程可以由多个线程组成,每个线程拥有独立的程序计数器、栈、寄存器等,并共享进程的资源,如内存和文件描述符。

线程ID(Thread ID)是操作系统为每个线程分配的唯一标识符。通过线程ID,可以区分和管理不同的线程。在不同的操作系统中,线程ID的表示方式可能有所差异,例如,在Linux中,线程ID是一个无符号整数;而在Windows中,线程ID是一个句柄。

线程的主要优点是能够实现并发执行,提高程序的响应速度和资源利用率。多线程的应用场景包括但不限于并行计算、多任务处理、GUI界面的响应和网络编程等。

在使用线程的过程中,通常需要创建、启动、等待和销毁线程。创建线程可以通过操作系统提供的线程库函数(如pthread_createCreateThread等)来完成,创建线程时需要指定线程的入口函数和参数。启动线程后,线程将开始执行指定的函数,并且可以与其他线程并发执行。等待线程的结束通常使用类似pthread_joinWaitForSingleObject等函数,以等待线程的终止并获取其返回值。销毁线程可以通过调用相应的线程库函数(如pthread_exitExitThread等)来实现。

需要注意的是,线程的创建和管理涉及到资源分配和同步等问题,需要仔细设计和编码,以确保线程的正确性和稳定性。此外,多线程编程也面临一些挑战,如竞态条件、死锁、资源争用等问题,需要采取适当的同步和互斥机制来解决

同步等问题,需要仔细设计和编码,以确保线程的正确性和稳定性。此外,多线程编程也面临一些挑战,如竞态条件、死锁、资源争用等问题,需要采取适当的同步和互斥机制来解决

你可能感兴趣的:(UNIX,unix,网络,服务器)