C语言进程和线程
  1. 什么是程序?
    程序是一系列指令的集合,用于告诉计算机如何执行特定的任务。它由一组逻辑和算法组成,以解决特定问题或完成特定功能。
  2. 什么是进程

    先给一个定义:进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器、寄存器和程序变量的当前值。

  3. 进程有哪些特征?

    1. 进程依赖于程序运行而存在,进程是动态的,程序是静态的;

    2. 进程是操作系统进行资源分配和调度的一个独立单位(CPU除外,线程是处理器任务调度和执行的基本单位);

    3. 每个进程拥有独立的地址空间,地址空间包括代码区、数据区和堆栈区,进程之间的地址空间是隔离的,互不影响。

  4. 什么是线程?
    线程是进程中的一个执行单元,它是操作系统进行调度和执行的最小单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间、文件句柄等。不同于进程之间相对独立的执行,线程在同一进程中并发执行,共享相同的上下文环境。
  5. 进程和线程的区别
    • 本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
    • 包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
    • 资源开销:每个进程都有独立的地址空间,进程之间的切换会有较大的开销;线程可以看做轻量级的进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
    • 影响关系:一个进程崩溃后,在保护模式下其他进程不会被影响,但是一个线程崩溃可能导致整个进程被操作系统杀掉,所以多进程要比多线程健壮。
  6. 进程的三个状态:就绪、运行、阻塞
  7. 线程的五个状态:创建、就绪、运行、阻塞、死亡
  8. fork函数:
    //功能:创建一个子进程;
    //头文件: #include <unistd.h>
    //fork会创建一个子进程,子进程会拷贝父进程的所有内容。一旦fork执行完就有两个进程在执行。当父进程执行时,fork返回子进程的pid(pid>0).父进程执行时,fork返回0.
    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
        pid_t pid;
        pid = fork();
        if(pid == 0)
        {
            printf("child is running\n");
        }
        else if(pid > 0)
        {
            sleep(1);
            printf("parent is running\n");
        }
        return 0;
    }
    //输出:
    child is running
    parent is running
    //父进程创建子进程,子进程会拷贝父进程资源,然后两个进程空间完全独立,子进程某个变量改变不会影响父进程的。
    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
        int count = 0;
        pid_t pid;
        pid = fork();
        if(pid == 0)
        {
            count++;
            printf("child is running\n");
        }
        else if(pid > 0)
        {
            sleep(1);
            printf("parent is running\n");
        }
        printf("count is %d\n", count);
        return 0;
    }
    //输出结果:
    child is running
    count is 1
    parent is running
    count is 0
  9. wait函数
    //功能:当父进程执行此函数时,父进程阻塞等待子进程结束,回收子进程资源。
    //原型:pid_t wait(int *status);
    //参数:status,输出参数,里面保存的是子进程结束时的状态
    //返回值:pid_t,结束的那个子进程的id
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    int main()
    {
        pid_t pid;
        pid = fork();
        if(pid == 0)
        {
            sleep(1);
            printf("child is over\n");
            exit(1);
        }
        else if(pid > 0)
        {
            int err;
            wait(&err);
            printf("parent is running\n");
            printf("err is %d\n", err);
        }
        exit(0);
        }
  10. waitpid函数
    //功能:等待指定子进程结束
    //原型: pid_t waitpid(pid_t pid, int *status, int options);
    /*参数:pid    指定的子进程的id
            status  子进程结束时的状态
            options 指定以哪种方式等待子进程结束(WNOHANG-不阻塞等待;0-一直阻塞)
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    int main()
    {
        pid_t pid;
        pid = fork();
        if(pid == 0)
        {
            sleep(5);
            printf("child over\n");
            exit(1);
        }
        else if(pid > 0)
        {
            while(1)
            {
                int ret = waitpid(pid, NULL, WNOHANG);
                if(ret == pid)
                {
                    printf("%d over\n", pid);
                    break;
                }
                else
                {
                    printf("parent running\n");
                    sleep(1);
                }
            }
        }
    }
    结果:
    parent running
    parent running
    parent running
    parent running
    parent running
    child over
    450189 over
  11. 僵尸进程:子进程结束,父进程没有结束,且父进程没调用wait等函数回收子进程的资源,此时子进程变成僵尸进程。
  12. pthread_create函数
    //功能:用于创建新线程
    //原型:int pthread_create(pthread_t *thread, pthread_attr_t *attr, coid *(*start_routine)(void *), void *arg)
    /*参数:thread[出参]:输出值,创建线程时,系统会返回出一个线程id
            attr[入参]:创建线程时,指定线程的属性,可以为NULL
            start_routine:创建线程后执行的函数
            arg:为start_routine服务,是传递给start_routine的参数
    */
    #include <stdio.h>
    #include <pthread.h>
    void *fun(void *p)
    {
        while(1)
        {
            printf("thread is running\n");
            sleep(1);
        }
    }
    int main()
    {
        pthread_t tid;
        pthread_create(&tid, NULL, fun, NULL);
        while(1)
        {
            printf("main is running\n");
            sleep(1);
        }
    }
    //编译: gcc thread.c -o thread -lpthread
    //结果:
    main is running
    thread is running
    main is running
    thread is running
  13. 线程间同步和互斥
    互斥:两个或多个线程共同访问一个共享资源,只有一个线程能够获取并访问资源。

    1. 互斥锁:
      1. 定义互斥锁:pthread_mutex_t mutex;
      2. 初始化互斥锁:pthread_mutex_init(&mutex, NULL);
      3. 加锁:pthread_mutex_lock(&mutex);
      4. 解锁:pthread_mutex_unlock(&mutex);
      5. 销毁互斥锁:pthread_mutex_destroy(&mutex);
    2. 信号量:多用于同步,头文件semaphore.h
      1. 定义信号量:sem_t sem;
      2. 创建信号量:sem_init(&sem, 0, 3);//3表示有3个共享资源
      3. 请求信号量:sem_wait(&sem);//请求成功后,共享资源数减1
      4. 释放信号量: sem_post(&sem);//释放后共享资源数加1
      5. 销毁信号量:sem_destroy(&sem);
  14. 使用信号量循环打印M Y
    #include <stdio.h>
    #include <pthread.h>
    #include <semaphore.h>
    sem_t sem;
    void *fun1()
    {
        while(1)
        {
            sleep(1);
            printf("M\n");
            sem_post(&sem);
        }
    }
    void *fun2()
    {
        while(1)
        {
            sem_wait(&sem);
            printf("Y\n");
        }
    }
    int main()
    {
        pthread_t pid1, pid2;
        sem_init(&sem, 0, 0);
        pthread_create(&pid1, NULL, fun1, NULL);
        pthread_create(&pid2, NULL, fun2, NULL);
        pthread_join(pid1, NULL);
    }
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
error: Content is protected !!内容保护!!