C语言函数大全-- k 开头的函数

C语言函数大全

本篇介绍 C语言函数大全-- k 开头的函数

1. kill

1.1 函数说明

函数声明 函数功能
int kill(pid_t pid, int sig); 向指定进程或进程组发送一个信号

参数:

  • pid: 目标进程的 ID(进程ID或进程组ID)
  • sig: 要发送的信号编号

1.2 演示示例

#include 
#include 
#include 
#include 

void my_handler(int signum)
{
    printf("Received signal %d\n", signum);
}

int main()
{
    pid_t pid;
    int ret;

    pid = fork(); // 创建子进程
    if (pid == 0) {
        // 子进程
        printf("Child process started\n");
        sleep(10); // 等待父进程发送信号
        exit(0);
    } else if (pid > 0) {
        // 父进程
        printf("Parent process started\n");
        sleep(5); // 等待子进程创建完毕
        ret = kill(pid, SIGINT); // 向子进程发送 SIGINT 信号
        if (ret == -1) {
            perror("kill failed");
            exit(EXIT_FAILURE);
        }
        printf("Signal sent successfully\n");
        wait(NULL); // 等待子进程结束
        printf("Child process finished\n");
        exit(EXIT_SUCCESS);
    } else {
        perror("fork failed");
        exit(EXIT_FAILURE);
    }

    return 0;
}

上述示例程序中,我们首先创建一个子进程,并在子进程中等待 10 秒钟。然后,在父进程中发送 SIGINT 信号给子进程,并等待子进程结束。当子进程收到 SIGINT 信号时,会调用 my_handler() 函数来处理信号。

2. kbhit

2.1 函数说明

函数声明 函数功能
int kbhit(void); 在控制台中检测是否有按键被按下

如果有按键被按下,该函数返回非零值,否则返回 0。

2.2 演示示例

#include 
#include 

int main()
{
    int ch;

    printf("Press any key to continue...\n");
    while (!kbhit()) {
        // 等待用户按键
    }
    ch = getch(); // 获取用户按下的键值
    printf("You pressed the '%c' key\n", ch);

    return 0;
}

2.3 运行结果

C语言函数大全-- k 开头的函数_第1张图片

3. kprintf

3.1 函数说明

函数声明 函数功能
void kprintf(const char *format, ...); 用于嵌入式系统中输出调试信息

注意: 该函数原型和使用方法与标准库中的 printf() 函数类似。不同的是,kprintf() 函数通常需要根据具体的嵌入式系统进行修改,以适应不同的输出方式。

3.2 演示示例

#include 
#include 
#include 
#include 

int uart_fd = -1; // 串口文件描述符

void kprintf(const char *format, ...)
{
    va_list ap;
    char buf[256];

    va_start(ap, format);
    vsnprintf(buf, sizeof(buf), format, ap);
    va_end(ap);

    if (uart_fd != -1) {
        write(uart_fd, buf, strlen(buf));
    }
}

int init_uart(const char *devname)
{
    struct termios tio;

    uart_fd = open(devname, O_RDWR | O_NOCTTY);
    if (uart_fd == -1) {
        perror("open failed");
        return -1;
    }

    memset(&tio, 0, sizeof(tio));
    cfmakeraw(&tio);
    cfsetspeed(&tio, B115200);
    tcsetattr(uart_fd, TCSANOW, &tio);

    return 0;
}

int main()
{
    int ret;

    ret = init_uart("/dev/ttyS0"); // 打开 ttyS0 串口
    if (ret == -1) {
        exit(EXIT_FAILURE);
    }

    kprintf("Hello, world!\n"); // 输出调试信息

    close(uart_fd); // 关闭串口文件描述符
    return 0;
}

上述示例程序中,首先通过 init_uart() 函数打开了 ttyS0 串口,并将其设置为 RAW 模式和波特率 115200。然后,在 main() 函数中调用了 kprintf() 函数来输出一条调试信息。该函数会将调试信息写入 ttyS0 串口中,并发送到外部设备(如 PC)上。

注意:kprintf() 函数通常需要进行一定的修改以适应具体的嵌入式系统和调试工具,上面仅提供一个简单的示例,不能直接在所有系统中使用。

4. kmem_cache_alloc

4.1 函数说明

函数声明 函数功能
void *kmem_cache_alloc(struct kmem_cache *cachep, int flags); 它是 Linux 内核中的一个函数,用于从指定的内存缓存中分配一个对象

参数:

  • cachep: 指向所需缓存区的指针
  • flags: 用于控制内存分配方式的标志。

4.2 演示示例

#include 
#include 
#include 
#include 

struct my_struct {
    int a;
    char b;
};

static struct kmem_cache *my_cachep;

int my_init(void)
{
    struct my_struct *obj;

    printk(KERN_INFO "Initializing module...\n");

    my_cachep = kmem_cache_create("my_cache", sizeof(struct my_struct), 0, SLAB_HWCACHE_ALIGN, NULL);
    if (!my_cachep) {
        printk(KERN_ERR "kmem_cache_create failed\n");
        return -1;
    }

    obj = kmem_cache_alloc(my_cachep, GFP_KERNEL);
    if (!obj) {
        printk(KERN_ERR "kmem_cache_alloc failed\n");
        return -1;
    }

    obj->a = 123;
    obj->b = 'A';

    printk(KERN_INFO "obj->a = %d, obj->b = '%c'\n", obj->a, obj->b);

    return 0;
}

void my_exit(void)
{
    printk(KERN_INFO "Exiting module...\n");

    kmem_cache_free(my_cachep, obj);

    kmem_cache_destroy(my_cachep);
}

MODULE_LICENSE("GPL");
module_init(my_init);
module_exit(my_exit);

上述示例程序中,首先使用 kmem_cache_create() 函数创建了一个名为 my_cache 的内存缓存区,该缓存区能够容纳 struct my_struct 类型的对象。然后,在 my_init() 函数中使用 kmem_cache_alloc() 函数从缓存区中分配了一个 struct my_struct 类型的对象,并进行了初始化操作。最后,在 my_exit() 函数中使用 kmem_cache_free() 函数释放了该对象所占用的内存,然后销毁了整个缓存区。

注意: kmem_cache_alloc() 函数和其他 Linux 内核函数在用户空间下无法直接使用,通常需要编写内核模块来调用这些函数。

5. kmem_cache_free

5.1 函数说明

函数声明 函数功能
void kmem_cache_free(struct kmem_cache *cachep, void *objp); 它是 Linux 内核中的一个函数,用于将之前使用 kmem_cache_alloc() 函数分配的对象释放回内存缓存池,以便下次再次分配使用。

参数:

  • cachep: 指向之前使用的缓存区的指针
  • objp: 要释放的对象的指针。

5.2 演示示例

参考 4.2 所示

注意: kmem_cache_free() 函数和其他 Linux 内核函数在用户空间下无法直接使用,通常需要编写内核模块来调用这些函数。

6. kmem_cache_destroy

6.1 函数说明

函数声明 函数功能
void kmem_cache_destroy(struct kmem_cache *cachep); 它是 Linux 内核中的一个函数,用于销毁之前使用 kmem_cache_create() 函数创建的内存缓存区。

参数:

  • cachep: 指向要销毁的缓存区的指针

6.2 演示示例

参考 4.2 所示

注意: 在销毁缓存区之前,必须确保所有从缓存区中分配的内存都已经被释放,否则可能会导致内存泄漏或其他问题。

7. kmalloc

7.1 函数说明

函数声明 函数功能
void *kmalloc(size_t size, gfp_t flags); 它是 Linux 内核中的一个函数,用于在内核中分配指定大小的内存空间。

参数:

  • size: 表示要分配的内存大小
  • flags: 表示一组标志位,用于控制内存分配方式。

7.2 演示示例

#include 
#include 
#include 
#include 

int my_init(void)
{
    void *ptr;

    printk(KERN_INFO "Initializing module...\n");

    ptr = kmalloc(1024, GFP_KERNEL);
    if (!ptr) {
        printk(KERN_ERR "kmalloc failed\n");
        return -1;
    }

    /* do something with ptr */

    kfree(ptr);

    return 0;
}

void my_exit(void)
{
    printk(KERN_INFO "Exiting module...\n");
}

MODULE_LICENSE("GPL");
module_init(my_init);
module_exit(my_exit);

上述示例程序中,在 my_init() 函数中我们使用 kmalloc() 函数分配了一个大小为 1024 字节的内存空间,并且对于成功与否进行了检查。然后,在处理完该内存区域之后,使用 kfree() 函数释放了所占用的内存。

注意: 在使用 kmalloc() 函数分配内存时,必须确保所分配的内存不会造成内核堆栈溢出或其他安全问题。另外,由于 kmalloc() 函数返回的内存地址可能不是连续的,因此在使用该函数分配大块内存时,需要特别注意内存对齐和分配方式等问题。

8. kzalloc

8.1 函数说明

函数声明 函数功能
void *kzalloc(size_t size, gfp_t flags); 它是 Linux 内核中的一个函数,用于分配指定大小的内存空间,并将其初始化为零。

参数:

  • size: 表示要分配的内存大小
  • flags: 表示一组标志位,用于控制内存分配方式。

8.2 演示示例

c
#include 
#include 
#include 
#include 

int my_init(void)
{
    void *ptr;

    printk(KERN_INFO "Initializing module...\n");

    ptr = kzalloc(1024, GFP_KERNEL);
    if (!ptr) {
        printk(KERN_ERR "kzalloc failed\n");
        return -1;
    }

    /* do something with ptr */

    kfree(ptr);

    return 0;
}

void my_exit(void)
{
    printk(KERN_INFO "Exiting module...\n");
}

MODULE_LICENSE("GPL");
module_init(my_init);
module_exit(my_exit);

上述示例程序中,在 my_init() 函数中使用 kzalloc() 函数分配了一个大小为 1024 字节的内存空间,并将其初始化为零。然后,在处理完该内存区域之后,使用 kfree() 函数释放了所占用的内存。

注意: 虽然可以使用 kmalloc() 函数分配内存然后手动初始化为零,但是使用 kzalloc() 函数可以更加高效和简单地完成这个操作。另外,由于 kzalloc() 函数返回的内存地址是经过清零的,因此在使用该函数分配内存时,无需显式调用 memset() 等函数进行初始化操作。

9. kfree

9.1 函数说明

函数声明 函数功能
void kfree(void *ptr); 它是 Linux 内核中的一个函数,用于释放使用 kmalloc() 或者 kzalloc() 函数分配的内存空间。

参数:

  • ptr : 指向要释放的内存块的指针。

9.2 演示示例

参考 7.2 所示

注意: 在使用 kfree() 函数释放内存时,必须确保所释放的内存是由 kmalloc() 或者 kzalloc() 函数分配的,否则可能会导致内核崩溃或其他问题。另外,使用 kfree() 函数释放一个指针之后,应该将其设置为 NULL,以避免出现悬挂指针(dangling pointer)等问题。

10. keep

10.1 函数说明

函数声明 函数功能
void keep(void *ptr); 它是 Linux 内核中的一个函数,用于防止编译器将指定的符号优化掉。

参数:

  • ptr: 是指向要保留的符号的指针。

10.2 演示示例

#include 
#include 
#include 

static int my_symbol __attribute__((__used__));

int my_init(void)
{
    printk(KERN_INFO "Initializing module...\n");

    my_symbol = 123;

    /* do something with my_symbol */

    keep(&my_symbol); // 保留符号

    return 0;
}

void my_exit(void)
{
    printk(KERN_INFO "Exiting module...\n");
}

MODULE_LICENSE("GPL");
module_init(my_init);
module_exit(my_exit);

上述示例程序中,在 my_init() 函数中定义了一个整型变量 my_symbol,并且对其进行了初始化。然后,在处理完该变量之后,调用 keep() 函数保留该符号,以避免编译器将其优化掉。

注意: 在使用 keep() 函数时,必须确保所保留的符号不会被优化掉,否则可能会导致程序出错或崩溃。另外,由于 keep() 函数只是防止编译器优化符号,并不会改变其可见性或访问权限,因此在使用该函数时,应该确保所保留的符号在需要的位置上是可见和可访问的。

参考

  1. [API Reference Document]

你可能感兴趣的:(开发语言-C,C语言函数大全,k,开头的函数)