GCC扩展功能、函数,预处理命令

news2024/10/6 6:24:22

文章目录

  • 前言
  • 一、GCC C语言扩展
    • 声明函数属性
    • 变量属性
    • 内敛汇编
    • 与原子操作相关的内建函数
      • 内存模型感知原子操作的内置函数
      • 使用溢出检查执行算术的内置函数
    • - xxx
  • 二、GCC C++语言扩展
    • interface和 pragmas
    • Template
  • 二、预处理过程及其指令
    • 预处理过程
      • 1. 字符集转换
      • 2. Initial processing
      • 3. token化和
      • 4. 预处理语言
    • 头文件
    • 宏命令
      • 标准预定义宏
      • comman predefined macros
    • 条件
    • xx
  • experiment
  • reference


前言

GCC(GNU Compiler Collection)提供了许多扩展功能,这些功能在标准C和C++中没有定义,但可以提高代码的效率和可移植性。


一、GCC C语言扩展

  • 128位的整数

    _int128 i_128;
    unsigned _int128 ui_128;
    
  • 线程私有变量 Thread-local storage (TLS)

    // 每个线程会有自己独立的变量a
    __thread static int a = 9;
    
  • 零长度数组

    // 可用于定义协议头等
    typedef struct line{
      int length;
      char contents[0];
    } line;
    line* l = (line*)malloc(sizeof(line) + 100)
    l->contents[99];
    
  • 具有可变参数的宏

    #define debug1(format, ...) fprintf (stderr, format, __VA_ARGS__)     // debug1("abc") is invalid
    #define debug2(format, args...) fprintf (stderr, format, args)        // debug2("abc") is invalid
    #define debug3(format, ...) fprintf (stderr, format, ## __VA_ARGS__)  // debug3("abc") is valid
    
  • struct和数组指定初始化

    int a[6] = { [4] = 29, [2] = 15 };//{ 0, 0, 15, 0, 29, 0 };
    int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
    struct point p = { .y = yvalue, .x = xvalue };
    
  • 范围case

    case 'A' ... 'Z':
    case 1 ... 5:
    

声明函数属性

GNU C/C++
在函数声明处添加形如:,指定函数属性
__attribute__((xxx))

  • alias(“target”)
    alias属性导致声明作为另一个符号的别名发出

    void __f () { /* Do something. */; }
    void f () __attribute__ ((weak, alias ("__f")));
    
  • aligned (alignment)
    对齐属性指定函数的第一条指令的最小对齐,以字节为单位, alignment必须是 an integer constant power of 2

  • constructor destructor constructor(priority) destructor(priority)
    constructor属性会使得函数在main()之前执行;deconstructor会使得函数在main()之后或exit()之后执行,constructor priority数值越小优先级越高,deconstructor与之相反。
    另外,c++的静态对象和constructor属性的函数的顺序不确定?

  • 函数弃用报警,deprecated

    __attribute__((deprecated("this function will removed in the future, please use xx instand"))) void old_fun();
    
  • noreturn

    void fatal () __attribute__ ((noreturn));
    
    void
    fatal (/* … */)
    {
      /* … */ /* Print error message. */ /* … */
      exit (1);
    }
    
  • section (“section-name”)
    默认情况下,编译器将其生成的代码放在text section。有时你需要额外的sections,将函数放置在某个sections中,section属性正是用来做这件事的

    extern void foobar (void) __attribute__ ((section ("bar")));
    
  • visibility (“visibility_type”)
    该属性影响链接时该函数是否可见。
    四种类型:default, hidden, protected or internal visibility

    • default
      默认可见性。可被其他模块、共享库可见,也意味着声明实体被覆盖。在语言中对应“外部链接”。
    • hidden
      模块外部不可见

变量属性

  • section (“section-name”)
    默认情况下,编译器将对象放在data section或bss section。

    struct duart a __attribute__ ((section ("DUART_A"))) = { 0 };
    struct duart b __attribute__ ((section ("DUART_B"))) = { 0 };
    char stack[10000] __attribute__ ((section ("STACK"))) = { 0 };
    int init_data __attribute__ ((section ("INITDATA")));
    
    main()
    {
      /* Initialize stack pointer */
      init_sp (stack + sizeof (stack));
    
      /* Initialize initialized data */
      memcpy (&init_data, &data, &edata - &data);
    
      /* Turn on the serial ports */
      init_duart (&a);
      init_duart (&b);
    }
    

    未初始化的变量放在common(or bss) section。使用section属性会更改变量进入的部分,如果未初始化的变量有多个定义,则可能导致链接器发出错误。可以使用-fno公共标志或nocommon属性强制初始化变量。

  • visibility (“visibility_type”)
    详细定义见 声明函数属性

  • aligned (alignment)
    alignment=power(2, x)

    struct __attribute__ ((aligned (8))) S { short f[3]; };
    typedef int more_aligned_int __attribute__ ((aligned (8)));
    

内敛汇编

asm关键字允许在C代码中内嵌汇编指令。GCC提供李彤两种格式的内嵌汇编。1.基础形式,没有operands 2.扩展形式,有operands

  • asm asm-qualifiers ( AssemblerInstructions )

    /* Note that this code will not compile with -masm=intel */
    #define DebugBreak() asm("int $3")
    
asm asm-qualifiers ( AssemblerTemplate 
                 : OutputOperands 
                 [ : InputOperands
                 [ : Clobbers ] ])

asm asm-qualifiers ( AssemblerTemplate 
                      : OutputOperands
                      : InputOperands
                      : Clobbers
                      : GotoLabels)
int src = 1;
int dst;   

asm ("mov %1, %0\n\t"
    "add $1, %0"
    : "=r" (dst) 
    : "r" (src));

printf("%d\n", dst);

与原子操作相关的内建函数

内存模型感知原子操作的内置函数

  以下内建函数基本匹配了C++11内存模型的需求。它们都是以“__atomic”为前缀进行标识的,大多数都是重载的,因此可以与多种类型一起使用。
  这些函数意在代替__sync。它们的主要不同为,内存序是作为函数的参数。
  注意到,__atomic假设程序遵守C++11内存模型。尤其是程序是自由数据竞争的。详见C++11标准。
  __atomic可被用于1,2,4,8字节的任意整数,16字节类型的整数__nt28也是支持的。
  四个非算数运算函数(load, store, exchage, compare_exchange)也都有通用版本。通用版本工作在任意数据类型上。它使用lock-free内建函数,否则,外部调用将在运行时解决。此外部调用的格式与添加的“size_t”参数相同,该参数作为指示所指向对象大小的第一个参数插入。所有对象的大小必须相同。

有6中内存序,和C++11中的内存模型对应。一个原子操作能够同时限制code motion和 映射到在线程之间同步的硬件指令。这种情况发生的程度受内存序的控制,这些顺序在这里以强度的近似升序列出。precise semantics见C++11内存模型。

  1. __ATOMIC_RELAXED
    暗示没有内部线程顺序限制。如果某个原子操作使用 relaxed 作为其 memory order,那么这个原子操作将退化为一个单纯的原子操作,不再具有线程同步节点的作用。
  2. __ATOMIC_CONSUME
  3. __ATOMIC_ACQUIRE
  4. __ATOMIC_RELEASE
  5. __ATOMIC_ACQ_REL
  6. __ATOMIC_SEQ_CST
// 返回 *ptr 的值
type __atomic_load_n (type *ptr, int memorder)

// atomic load的通用版本,将*ptr的值加载进*ret
void __atomic_load (type *ptr, type *ret, int memorder)

// 将val写入*ptr
void __atomic_store_n (type *ptr, type val, int memorder)

// 通用版本,将*val写入*ptr
void __atomic_store (type *ptr, type *val, int memorder)

// 原子交换操作,先返回*ptr的值,再将val写入*ptr
type __atomic_exchange_n (type *ptr, type val, int memorder)

// 通用版本,*ret=*ptr, *ptr=*val
void __atomic_exchange (type *ptr, type *val, type *ret, int memorder)

// 类似:{ *ptr op= val; return *ptr; }
// { *ptr = ~(*ptr & val); return *ptr; } // nand
// ptr指向的type对象必须是 整数或者指针类型,不能是布尔类型,支持所有内存模型
Built-in Function: type __atomic_add_fetch (type *ptr, type val, int memorder)
Built-in Function: type __atomic_sub_fetch (type *ptr, type val, int memorder)
Built-in Function: type __atomic_and_fetch (type *ptr, type val, int memorder)
Built-in Function: type __atomic_xor_fetch (type *ptr, type val, int memorder)
Built-in Function: type __atomic_or_fetch (type *ptr, type val, int memorder)
Built-in Function: type __atomic_nand_fetch (type *ptr, type val, int memorder)

// 类似:{ tmp = *ptr; *ptr op= val; return tmp; }
// { tmp = *ptr; *ptr = ~(*ptr & val); return tmp; } // nand
Built-in Function: type __atomic_fetch_add (type *ptr, type val, int memorder)
Built-in Function: type __atomic_fetch_sub (type *ptr, type val, int memorder)
Built-in Function: type __atomic_fetch_and (type *ptr, type val, int memorder)
Built-in Function: type __atomic_fetch_xor (type *ptr, type val, int memorder)
Built-in Function: type __atomic_fetch_or (type *ptr, type val, int memorder)
Built-in Function: type __atomic_fetch_nand (type *ptr, type val, int memorder)

// 先测试*(char*)ptr是否非空。再将其置为非空,最后返回先前的值。 ptr应当指向bool或者bool类型
bool __atomic_test_and_set (void *ptr, int memorder)

// 原子清除*ptr, *ptr=0, ptr应当指向bool或char类型
void __atomic_clear (bool *ptr, int memorder)

//  acts as a synchronization fence between threads based on the specified memory order.
void __atomic_thread_fence (int memorder)

// acts as a synchronization fence between a thread and signal handlers based in the same thread.
void __atomic_signal_fence (int memorder)

// ???
bool __atomic_always_lock_free (size_t size, void *ptr)
// ???
bool __atomic_is_lock_free (size_t size, void *ptr)

使用溢出检查执行算术的内置函数

以下内置函数允许执行简单的算术运算,同时检查运算是否溢出。

bool __builtin_add_overflow (type1 a, type2 b, type3 *res)
bool __builtin_sadd_overflow (int a, int b, int *res)
bool __builtin_saddl_overflow (long int a, long int b, long int *res)
bool __builtin_saddll_overflow (long long int a, long long int b, long long int *res)
bool __builtin_uadd_overflow (unsigned int a, unsigned int b, unsigned int *res)
bool __builtin_uaddl_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
bool __builtin_uaddll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

Built-in Function: bool __builtin_sub_overflow (type1 a, type2 b, type3 *res)
Built-in Function: bool __builtin_ssub_overflow (int a, int b, int *res)
Built-in Function: bool __builtin_ssubl_overflow (long int a, long int b, long int *res)
Built-in Function: bool __builtin_ssubll_overflow (long long int a, long long int b, long long int *res)
Built-in Function: bool __builtin_usub_overflow (unsigned int a, unsigned int b, unsigned int *res)
Built-in Function: bool __builtin_usubl_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
Built-in Function: bool __builtin_usubll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

Built-in Function: bool __builtin_mul_overflow (type1 a, type2 b, type3 *res)
Built-in Function: bool __builtin_smul_overflow (int a, int b, int *res)
Built-in Function: bool __builtin_smull_overflow (long int a, long int b, long int *res)
Built-in Function: bool __builtin_smulll_overflow (long long int a, long long int b, long long int *res)
Built-in Function: bool __builtin_umul_overflow (unsigned int a, unsigned int b, unsigned int *res)
Built-in Function: bool __builtin_umull_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
Built-in Function: bool __builtin_umulll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

以下函数与__builtin_add_overflow, __builtin_sub_overflow, or __builtin_mul_overflow相似,除了,它们不存储运算结果。

bool __builtin_add_overflow_p (type1 a, type2 b, type3 c)
bool __builtin_sub_overflow_p (type1 a, type2 b, type3 c)
bool __builtin_mul_overflow_p (type1 a, type2 b, type3 c)

例如,以下宏可用于在编译时便携式检查添加两个常量整数是否会溢出,并仅在已知安全且不会触发-Woverflow警告的情况下执行添加。

#define INT_ADD_OVERFLOW_P(a, b) \
   __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)

enum {
    A = INT_MAX, B = 3,
    C = INT_ADD_OVERFLOW_P (A, B) ? 0 : A + B,
    D = __builtin_add_overflow_p (1, SCHAR_MAX, (signed char) 0)
};

- xxx

  • 函数名作为字符串
    GCC提供三个magic constants用以持有当前函数名的字符串
  • __func__ : C99标准的一部分
  • __FUNCTION__ :是__func__的另一个名称,用于与旧版本的GCC向后兼容。
  • __PRETTY_FUNCTION__ :__func__的另一个名字,在C++中包含了函数签名
extern "C" int printf (const char *, ...);

class a {
 public:
  void sub (int i)
    {
      printf ("__FUNCTION__ = %s\n", __FUNCTION__);
      printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);
    }
};

int
main (void)
{
  a ax;
  ax.sub (0);
  return 0;
}
  • 获取函数的返回地址或帧地址
    void * __builtin_return_address (unsigned int level)

二、GCC C++语言扩展

interface和 pragmas

#pragma para

https://www.cnblogs.com/zhoug2020/p/6616942.html
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/gcc/C_002b_002b-Interface.html

Template

C++ 是 language feature

二、预处理过程及其指令

预处理过程

1. 字符集转换

将文件转换为用于内部处理的字符集。

2. Initial processing

执行一系列文本转换。

  1. 读取文件到内存并分行
    GCC将LF, CR LF 和 CR作为行结束标识。
    The C standard says that this condition provokes undefined behavior, so GCC will emit a warning message.似乎并没有警告
  2. 三字符转换(添加 -trigraphs 选项)(默认 -Wtrigraphs)
    Trigraph:       ??(  ??)  ??<  ??>  ??=  ??/  ??'  ??!  ??-
    Replacement:      [    ]    {    }    #    \    ^    |    ~
    
  3. 连续行合并
    以为 \结尾的行与下一行合并。
    \和`换行符之间不能有任何空格,否则预处理器会报错
  4. 所有注释替换为单个空格
/\
*
*/ # /*
*/ defi\
ne FO\
O 10\
20

3. token化和

#define foo() bar
foo()baz
     → bar baz
not
     → barbaz
    
a+++++b
	→ a ++ ++ + b

预处理标记分为五大类:标识符、预处理数字、字符串文字、标点符号和其他。标识符与C中的标识符相同:任何以字母或下划线开头的字母、数字或下划线序列。C的关键字对预处理器没有意义;它们是普通的标识符。例如,可以定义名称为关键字的宏。定义了可以被视为预处理关键字的唯一标识符。

4. 预处理语言

token化后,tokens流可能会被直接传输给 compiler’s parser。然后,如果包含预处理语言,则会先进行转换。这是大多数人认为的预处理器的工作。

预处理语言由要执行的指令和要扩展的宏组成。:

  • 包含头文件。这些是可以替换到程序中的声明文件。
  • 宏展开。您可以定义宏,宏是C代码任意片段的缩写。预处理器将在整个程序中用宏的定义替换宏。某些宏是自动为您定义的。
  • 条件编译。您可以根据各种条件包括或排除程序的各个部分。
  • 线路控制。如果使用程序将源文件组合或重新排列为中间文件,然后进行编译,则可以使用行控制来通知编译器每个源行的原始来源。
  • 诊断。您可以在编译时检测问题并发出错误或警告。

头文件

#include <file>  // 除comment之外的所有字符都是非法的

用于系统头文件。在系统目录的标准列表中搜索该文件。可以使用-I选项将目录前置到此列表中 。

#include "file" 

此变体用于您自己程序的头文件。它首先在包含当前文件的目录中搜索名为file的文件,然后在引号目录中搜索,然后在用于<file>的相同目录中搜索。您可以使用-iquote选项将目录前置到引号目录列表中。

header.h

#include "header.h"
// 无限include

搜索路径:
如果/a/b/c.h中包含#include"h1.h"则GCC首先会从/a/b/目录下搜索h1.h

standard system directories

cpp -v /dev/null -o /dev/null

宏命令

#define X 1
#undef

带宏参数

#define WARN_IF(EXP) \
do { if (EXP) \
        fprintf (stderr, "Warning: " #EXP "\n"); } \
while (0)
WARN_IF (x == 0);do { if (x == 0)
           fprintf (stderr, "Warning: " "x == 0" "\n"); } while (0);

字符串化

#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)"foo"
xstr (foo)xstr (4)str (4)"4"

连接

#define COMMAND(NAME)  { #NAME, NAME ## _command }

struct command commands[] =
{
  COMMAND (quit),
  COMMAND (help),};

	->
		struct command commands[] =
		{
		  { "quit", quit_command },
		  { "help", help_command },};

具有可变参数的宏

标准预定义宏

__FILE__  // string
__LINE__  //  int  #line num 会重置该值
__func__  // string
__DATE__  // string compile time
__TIME__  // string compile time

__cplusplus  // C++ language macro

comman predefined macros

https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

条件

#ifdef MACRO

controlled text

#endif /* MACRO */
#if expression
	controlled text
#endif /* expression */

#if expression
	text-if-true
#else /* Not expression */
	text-if-false
#endif /* Not expression */

#if X == 1
	…
#elif X == 2
	…
#else /* X != 2 and X != 1*/
	…
#endif /* X != 2 and X != 1*/
#if defined (__vax__) || defined (__ns16000__)
#ifdef __vax__
#error "Won't work on VAXen.  See comments at get_last_object."
#endif

#if !defined(FOO) && defined(BAR)
#error "BAR requires FOO."
#endif

xx

_Pragma ("GCC dependency \"parse.y\"")

#define DO_PRAGMA(x) _Pragma (#x)
DO_PRAGMA (GCC dependency "parse.y")

如果某个头文件中有#pragma once,该文件只会在C文件中出现一次
#gragma pack(<opt:pow(2, x>)指定后续结构体内存对齐的字节数

experiment

spin lock, sleep lock

#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <thread>

using namespace std;


int a;
unsigned char atomic_int = 0;

void* call_fun(void*)
{
    
    for (size_t i = 0; i < 100000; i++)
    {
        while (__atomic_exchange_n(&atomic_int, 1, __ATOMIC_RELAXED) != 0)
        {
            sched_yield();  // sleep lock if true
        }
        
        ++a;
        usleep(1);
        // std::cout << "this is a:" << a << " endl" << std::endl;

        __atomic_clear(&atomic_int, __ATOMIC_RELAXED);
    }
    return NULL;
}

class spin_lock
{
private:
    unsigned char atom_char;
public:
    spin_lock(/* args */): atom_char(0) {}
    ~spin_lock() {}
    void lock()
    {
        while (__atomic_exchange_n(&atom_char, 1, __ATOMIC_RELAXED) != 0);
    }
    void unlock()
    {
        __atomic_clear(&atom_char, __ATOMIC_RELAXED);
    }
};

class sleep_lock
{
private:
    spin_lock sp_lock;
    unsigned char locked;
public:
    sleep_lock(/* args */): locked(0) {}
    ~sleep_lock() {}
    void lock()
    {
        sp_lock.lock();
        while (locked)
        {
            sp_lock.unlock();
            sched_yield();
            sp_lock.lock();
        }
        locked = 1;
        sp_lock.unlock();        
    }
    void unlock()
    {
        sp_lock.lock();
        locked = 0;
        sp_lock.unlock();
    }
};

class direct_sleep_lock
{
private:
    unsigned char atom_char;
public:
    direct_sleep_lock(/* args */): atom_char(0) {}
    ~direct_sleep_lock() {}
    void lock()
    {
        while (__atomic_exchange_n(&atom_char, 1, __ATOMIC_RELAXED) != 0)
        {
            sched_yield();
        }
    }
    void unlock()
    {
        __atomic_clear(&atom_char, __ATOMIC_RELAXED);
    }
};

direct_sleep_lock lock;
void* call_fun2(void*)
{
    for (size_t i = 0; i < 100000; i++)
    {
        lock.lock();
        ++a;
        usleep(1);
        lock.unlock();
    }
    return NULL;
}

int main()
{
    pthread_t ths[5];
    for (size_t i = 0; i < sizeof(ths)/sizeof(ths[0]); i++)
    {
        pthread_create(ths+i, NULL, call_fun2, NULL);
    }
    for (size_t i = 0; i < sizeof(ths)/sizeof(ths[0]); i++)
    {
        pthread_join(ths[i], NULL);
    }

    printf(".....a = %d\n", a);

}

reference

在线文档:https://gcc.gnu.org/onlinedocs/

C++11内存模型:https://www.cnblogs.com/dream397/p/17763965.html

preprocesser https://gcc.gnu.org/onlinedocs/cpp/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1905020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ISP和IAP原理解释

ISP和IAP ISP ISP的全称是&#xff1a;In System Programming&#xff0c;即在系统编程&#xff0c;该操作是通过MCU厂商出厂BootLoader来实现&#xff0c;通过ISP可以对主flash区域进行擦除、编程操作&#xff0c;还可以修改芯片的选项字节等。例如&#xff0c;GD32F30x用户…

Failed to get D-Bus connection: Operation not permitted

最近使用wsl安装了centOS7镜像&#xff0c;在系统中安装了docker服务&#xff0c;但是在执行systemctl start docker的时候遇到了&#xff1a;Failed to get D-Bus connection: Operation not permitted问题&#xff0c;查阅了很多资料都没有效果&#xff0c;最终找到了一种解决…

RabbitMQ(集群相关部署)

RabbitMQ 集群部署 环境准备&#xff1a;阿里云centos8 服务器&#xff0c;3台服务器&#xff0c;分别进行安装&#xff1b; 下载Erlang Erlang和RabbitMQ版本对照&#xff1a;https://www.rabbitmq.com/which-erlang.html 创建yum库配置文件 vim /etc/yum.repos.d/rabbi…

【web前端HTML+CSS+JS】--- CSS学习笔记02

一、CSS&#xff08;层叠样式表&#xff09;介绍 1.优势 2.定义解释 如果有多个选择器共同作用的话&#xff0c;只有优先级最高那层样式决定最终的效果 二、无语义化标签 div和span&#xff1a;只起到描述的作用&#xff0c;不带任何样式 三、标签选择器 1.标签/元素选择器…

分布式技术栈、微服务架构 区分

1.分布式技术栈 这些技术栈都是为了更好的开发分布式架构的项目。 &#xff08;大营销平台的系统框架如下图&#xff0c;扩展的分布式技术栈&#xff09; &#xff08;1&#xff09;Dubbo——分布式技术栈 DubboNacos注册中心是应用可以分布式部署&#xff0c;并且提供RPC接…

mmfewshot 框架概述、环境搭建与测试(一)

一、mmfewshot 框架概述 少样本学习的基本流程&#xff1a; 我们将为所有小样本学习任务引入一个简单的基线&#xff0c;以进一步说明小样本学习的工作原理。最明显的流程是微调。它通常包括两个步骤&#xff1a;在大规模数据集上训练模型&#xff0c;然后在小样本数据上进行微…

游戏AI的创造思路-技术基础-遗传算法

遗传算法&#xff0c;选对了遗传算子&#xff0c;那就是优秀的继承者&#xff0c;选错了&#xff0c;那就是传说在祸害遗千年~~~~~ 目录 1. 定义 2. 发展历史 3. 遗传算法的基本原理和流程 3.1. 基本原理 3.1.1.基本原理 3.1.2. 算法流程 3.1.3. 关键要素 3.2. 函数和方…

栈和队列---循环队列

1.循环队列的出现 &#xff08;1&#xff09;上面的这个就是一个普通的数据的入队和出队的过程我们正常情况下去实现这个入队和出队的过程&#xff0c;就是这个数据从这个队尾进入&#xff0c;从队头离开&#xff0c;但是这个加入的时候肯定是没有其他的问题的&#xff0c;直接…

Java多线程不会?一文解决——

方法一 新建类如MyThread继承Thread类重写run()方法再通过new MyThread类来新建线程通过start方法启动新线程 案例&#xff1a; class MyThread extends Thread {public MyThread(String name) {super(name);}Overridepublic void run() {for(int i0;i<10;i){System.out.…

java项目总结8

1.方法引用 1.方法引用概述 注意注意&#xff1a; 1.引用出必须是函数式接口 2.被引用的方法必须已经存在 3.被引用方法的型参和返回值需要跟抽象方法保持一致 4.被引方法的功能要满足当前需求 Arrays.sort(arr,Main::subtraction); Main是该类的名称&#xff0c;&#xff1a…

代码随想录算法训练营第二十七天 |56. 合并区间 738.单调递增的数字 968.监控二叉树 (可跳过)

56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;in…

linux固定主机ip

1.查看虚拟网络配置 NAT设置&#xff1a; 2.修改网卡配置文件 [rootlocalhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"static" DEFROUTE"yes"…

PD虚拟机不能复制Mac的文件怎么回事 PD虚拟机不能复制Mac的文件怎么办 Parallels Desktop怎么用

PD虚拟机不仅能提供跨系统协作的服务&#xff0c;还能进行虚拟机系统与原生系统间的文件共享、文本复制、文件复制等操作&#xff0c;让系统间的资源可以科学利用。但在实际操作过程中&#xff0c;PD虚拟机不能复制Mac的文件怎么回事&#xff1f;PD虚拟机不能复制Mac的文件怎么…

PDM系统中物料分类与编码规则生成方案

在企业管理软件中&#xff0c;PDM系统是企业管理的前端软件&#xff0c;用于管理研发图纸、BOM等数据&#xff0c;然后生成相关物料表或BOM&#xff0c;递交给后端ERP系统进行生产管理。在PDM系统中&#xff0c;有两种方式可以生成物料编码。 1第一种是用户可以通过软件接口将…

Open3D 点云的圆柱形邻域搜索

目录 一、概述 1.1原理 1.2应用 二、代码实现 2.1完整代码 2.2程序说明 三、实现效果 3.1原始点云 3.2搜索后点云 一、概述 1.1原理 圆柱邻域搜索的基本思想是确定点云中的哪些点位于给定圆柱的内部。一个圆柱可以由以下几个参数定义&#xff1a; 中心点&#xff1a;…

RedHat9 | Zabbix-Server监控服务部署

系统版本以及软件版本 使用的系统版本&#xff1a; Red Hat Enterprise Linux release 9.2 软件版本&#xff1a; zabbix-release-7.0-3.el9.noarchzabbix-web-7.0.0-release1.el9.noarchzabbix-web-mysql-7.0.0-release1.el9.noarchzabbix-web-deps-7.0.0-release1.el9.noar…

Vue3+.NET6前后端分离式管理后台实战(二十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(二十七)

C++ 函数高级——函数重载——基本语法

作用&#xff1a;函数名可以相同&#xff0c;提高复用性 函数重载满足条件&#xff1a; 1.同一个作用域下 2.函数名称相同 3.函数参数类型不同 或者 个数不同 或者 顺序不同 注意&#xff1a;函数的返回值不可以作为函数重载的条件 示例&#xff1a; 运行结果&#xff1a;

排序格式排序格式

排序格式排序格式

探讨4层代理和7层代理行为以及如何获取真实客户端IP

准备工作 实验环境 IP角色192.168.1.100客户端请求IP192.168.1.100python 启动的HTTP服务192.168.1.102nginx服务192.168.1.103haproxy 服务 HTTP服务 这是一个简单的HTTP服务&#xff0c;主要打印HTTP报文用于分析客户端IP #!/usr/bin/env python # coding: utf-8import …