[email protected] Article directoryProcess/thread related3Thread related5 background information background information 7 pthread create pthread create 30 ...">

当前位置:网站首页>Process/Thread related in Sandbox - 1

Process/Thread related in Sandbox - 1

2022-08-09 13:50:00 to raise pigs

[email protected]

进程/线程相关

线程相关

background information

The theoretical concepts of threads and processes are not repeated here.
Linux 中,The system does not know threads or processes,它只认识 task.

The following explanations are all Unix like Semantics about threads below.

主线程和子线程

  • 共享: user area,Except the stack area is not shared,The rest are shared.
  • 不共享: 栈区(当有 1 主 + 4 child thread time,The stack area will be divided equally 5 份)

A resource shared by multiple processes(fork、cloneout of the child process and the parent process):

  • 代码

  • 文件描述符

  • 内存映射区 –mmap
    A resource shared by multiple threads:

  • 全局变量

  • Thread number and thread ID 是有区别的
    查看方式: Find the process of the program ID后, ps -Lf $(pid),LWPThat column is the threadID.

pthread_create

  • 头文件:
#include<pthread.h>

pthread非linux系统的默认库, 需手动链接-线程库 -lpthread

  • 函数说明:
    返回成功时,由 tidp 指向的内存单元被设置为新创建线程的线程ID.a
    ttr参数用于指定各种不同的线程属性.
    新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg.
    如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构体中,然后把这个结构的地址作为arg的参数传入.

  • 函数定义

int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, void *(*start_rtn)(void*),void *arg);
  • 参数说明:
    第一个参数为指向线程标识符的指针.
    第二个参数用来设置线程属性.
    第三个参数是线程运行函数的起始地址.
    最后一个参数是运行函数的参数.

  • 返回值
    若线程创建成功,则返回0.若线程创建失败,则返回出错编号,并且*thread中的内容是未定义的.

  • 代码

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

int num = 13; //设置为全局变量,在全局区域,共享

void* myfun(void* arg);

int main(int argc, char *argv[])
{
    
    void* p = (void *)&num;  //Pass in an address(voi* 也是 4 个字节)
    pthread_t id[5] = {
    0};
    for (int i = 0; i < 5; i++) {
    
        pthread_create(&(id[i]), NULL, myfun, p);
        printf("i = %d, thread id: %ld\n", i, id[i]);
    }
    
    return 0;
}

void* myfun(void* arg)
{
    
    printf("num = %d, child thread id: %ld\n", (*((int *)arg))++, pthread_self());
    return NULL;
}

pthread_join

pthread_join()即是子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源.

注意,默认情况下,Resources do not follow child threadsexit或returnthe recycled.

  • 头文件:
#include <pthread.h>
  • 函数说明:
    thread_join()函数,以阻塞的方式等待thread指定的线程结束.当函数返回时,被等待线程的资源被收回.
    如果线程已经结束,那么该函数会立即返回.并且thread指定的线程必须是 joinable 的.
  • 函数定义
int pthread_join(pthread_t thread, void **retval);

thread: 线程标识符,即线程ID,标识唯一线程.
retval: 用户定义的指针,用来存储被等待线程的返回值.

  • 返回值
    0代表成功. 失败,返回的则是错误号.

  • 示例代码:

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

void *thread_function(void *arg) {
    
    int i;
    for (i = 0; i < 8; i++) {
    
        printf("Thread working... %d \n", i);
        sleep(1);
    }
    return NULL;
}

int main(void) {
    
    pthread_t mythread;

    if (pthread_create(&mythread, NULL, thread_function, NULL)) {
    
        printf("error creating thread.");
        abort();
    }
    if (pthread_join(mythread, NULL)) {
    
        printf("error join thread.");
        abort();
    }

    printf("thread done! \n");
    return 0;
}
/* 输出 Thread working...! 0 Thread working...! 1 Thread working...! 2 Thread working...! 3 Thread working...! 4 Thread working...! 5 Thread working...! 6 Thread working...! 7 thread done! */

如果去掉pthread_join的调用的话,
输出为:

thread done! 
Thread working... 0 
Process finished with exit code 0

也就是说,The child thread is too late to execute its function,It was forced to terminate because of the death of the parent thread.

pthread_detach

  • 头文件:
#include <pthread.h>
  • 函数说明:
    pthread_join()函数的替代函数,可回收创建时detachstate属性设置为PTHREAD_CREATE_JOINABLE的线程的存储空间.
    该函数不会阻塞父线程.
    pthread_join()函数用于只是应用程序在线程tid终止时回收其存储空间.

  • 函数定义

int pthread_detach(pthread_t tid);
  • 返回值
    thread_detach() 在调用成功完成之后返回零.其他任何返回值都表示出现了错误.

注意,即使如此,When the parent thread exits,The child thread will still force quit.

pthread_cancel

  • 函数说明:
    发送终止信号给thread线程,如果成功则返回0,否则为非0值.发送成功并不意味着thread会终止.

  • 函数定义:

int pthread_cancel(pthread_t thread)
  • 示例代码:
/** * @Author: 吉松阳 * @Date: 2021/9/26 * @Description: */

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

void print_message_function(void *ptr);

int main() {
    
    pthread_t thread1;
    pthread_create(&thread1, NULL, (void *) &print_message_function, (void *) 0);
    sleep(3);
    printf("main thread\n");
    pthread_cancel(thread1);
    sleep(7);
    exit(0);
}

void print_message_function(void *ptr) {
    
    pthread_detach(pthread_self());
    sleep(6);
    printf("child thread\n");
    pthread_exit(0);
}
// 实验证明 pthread_exit 确实起作用了

信号处理相关

raise

  • 头文件:
#include <signal.h>
  • 函数说明:
    C 库函数, 会促使生成信号 sig.sig 参数与 SIG 宏兼容.

  • 函数定义

// sig -- 要发送的信号码.
int raise(int sig)

查看所有信号:使用 kill -l

[email protected]:~$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2

值得注意的是,
当一个进程调用fork时,Because the child process copies the parent's stored image at the beginning,The address of the signal catch function is meaningful in the child process,So the child process inherits the signal handling method of the parent process.
But when the child process callsexec后,因为execRunning a new program overwrites the storage image inherited from the parent process.
Then the signal catch function has no meaning in the new program,所以execChanges any signal that was previously set to be captured to the default action.

  • 返回值
    如果成功该函数返回零,否则返回非零.

signal

  • 头文件:
#include <signal.h>
  • 函数说明:
    C 库函数,设置一个函数来处理信号,即带有 sig 参数的信号处理程序.

  • 函数定义

void (*signal(int sig, void (*func)(int)))(int)

参数说明:

  • sig – 在信号处理程序中作为变量使用的信号码.下面是一些重要的标准信号常量

  • func – 一个指向函数的指针.它可以是一个由程序定义的函数,也可以是下面预定义函数之一.

    • SIG_DFL 默认的信号处理程序.
    • SIG_IGN 忽视信号.
  • 返回值
    The function returns the previous signal handler

  • 实例代码

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>

void signal_catchfunc(int);

int main() {
    
    int ret;
    signal(SIGINT, signal_catchfunc);
    printf("开始生成一个信号\n");
    ret = raise(SIGINT);
    if (ret != 0) {
    
        printf("错误,不能生成SIGINT信号\n");
        exit(0);
    }
    printf("退出....\n");
    return 0;
}

void signal_catchfunc(int signal) {
    
    printf("捕获信号\n");
}

sandbox使用的信号

The totality of the signal60余个,这里只介绍一下sandbox中使用的信号.

SIGUSR1/SIGUSR2

SIGUSR1 用户自定义信号 默认处理:进程终止;
SIGUSR2 User-defined signals are handled by default:进程终止.

SIGSEGV

在POSIX兼容的平台上,SIGSEGVis a processAn invalid memory reference was performed,或发生段错误时发送给它的信号.
SIGSEGV的符号常量在头文件signal.h中定义.
因为在不同平台上,信号数字可能变化,Therefore it is better to use symbolic signal names.通常,It is the signal#11.
SIGSEGV维基百科

原网站

版权声明
本文为[to raise pigs]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/221/202208091244510773.html