当前位置: 首页 > article >正文

创建线程 ---- 实例

1、C语言 创建线程 执行2个不同的函数:

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

// 第一个线程要执行的函数
void* function1(void* arg) {
    printf("Function 1 is running\n");
    // 执行一些任务...
    return NULL;
}

// 第二个线程要执行的函数
void* function2(void* arg) {
    printf("Function 2 is running\n");
    // 执行一些任务...
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    // 创建第一个线程执行function1
    if (pthread_create(&thread1, NULL, function1, NULL) != 0) {
        perror("Failed to create thread 1");
        return EXIT_FAILURE;
    }

    // 创建第二个线程执行function2
    if (pthread_create(&thread2, NULL, function2, NULL) != 0) {
        perror("Failed to create thread 2");
        return EXIT_FAILURE;
    }

    // 等待第一个线程结束
    if (pthread_join(thread1, NULL) != 0) {
        perror("Failed to join thread 1");
        return EXIT_FAILURE;
    }

    // 等待第二个线程结束
    if (pthread_join(thread2, NULL) != 0) {
        perror("Failed to join thread 2");
        return EXIT_FAILURE;
    }

    printf("Both threads have finished\n");
    return EXIT_SUCCESS;
}

2、C 创建两个线程 通过传递数组 执行同一个函数 打印数组的内容:

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

// 线程要执行的函数,接受一个void*类型的参数,这里参数是一个指向整型数组的指针
void* print_array(void* arg) {
    int* array = (int*)arg;
    int size = 5;

    printf("Array contents: ");
    for (int i = 0; i < size; ++i) {
        printf("%d ", array[i]);
    }
    printf("\n");
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    int array1[] = {1, 2, 3, 4, 5};
    int array2[] = {6, 7, 8, 9, 10};

    // 创建第一个线程,传递array1作为参数
    if (pthread_create(&thread1, NULL, print_array, (void*)array1) != 0) {
        perror("Failed to create thread 1");
        return EXIT_FAILURE;
    }

    // 创建第二个线程,传递array2作为参数
    if (pthread_create(&thread2, NULL, print_array, (void*)array2) != 0) {
        perror("Failed to create thread 2");
        return EXIT_FAILURE;
    }

    // 等待第一个线程结束
    if (pthread_join(thread1, NULL) != 0) {
        perror("Failed to join thread 1");
        return EXIT_FAILURE;
    }

    // 等待第二个线程结束
    if (pthread_join(thread2, NULL) != 0) {
        perror("Failed to join thread 2");
        return EXIT_FAILURE;
    }

    printf("Both threads have finished\n");
    return EXIT_SUCCESS;
}

3、C 创建两个线程 访问一个全局变量:

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

// 全局变量
int global_variable = 0;

// 互斥锁
pthread_mutex_t lock;

// 线程要执行的函数
void* increment(void* arg) {
    // 锁定互斥锁
    pthread_mutex_lock(&lock);
    
    // 访问和修改全局变量:实际上是对锁进行操作,把内容放在 锁->内容ops->解锁 中
    
    // 这里可以加上 内核那本书里面的设计与实现 什么时候需要加锁!
    global_variable++;
    printf("Global variable incremented to: %d\n", global_variable);
    
    // 解锁互斥锁
    pthread_mutex_unlock(&lock);
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    // 初始化互斥锁
    if (pthread_mutex_init(&lock, NULL) != 0) {
        perror("Failed to initialize mutex");
        return EXIT_FAILURE;
    }

    // 创建两个线程
    if (pthread_create(&thread1, NULL, increment, NULL) != 0) {
        perror("Failed to create thread 1");
        return EXIT_FAILURE;
    }
    if (pthread_create(&thread2, NULL, increment, NULL) != 0) {
        perror("Failed to create thread 2");
        return EXIT_FAILURE;
    }

    // 等待两个线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&lock);

    printf("Final value of global variable: %d\n", global_variable);
    return EXIT_SUCCESS;
}

读取-修改竞态条件(Read-Modify-Write Race Condition):当一个线程正在读取变量的值时,另一个线程可能会修改这个变量。如果第一个线程在读取过程中第二个线程改变了变量的值,第一个线程可能会得到一个不一致的值。

内存可见性问题:在某些编译器和处理器优化下,没有锁的保护可能导致一个线程看不到另一个线程对共享变量所做的修改,因为编译器和处理器可能会对内存访问进行重排序。

数据依赖性问题:如果shared_data的值依赖于程序中的其他状态,并且这些状态可能被其他线程修改,那么即使只是读取shared_data,也需要确保在读取时这些依赖状态不会被改变。

为了保证线程安全和数据的一致性,即使是读取操作,也应该在修改和读取共享变量时使用互斥锁。这样可以确保在任何时候只有一个线程能够访问共享变量,无论是读取还是写入。

在实际应用中,如果性能是一个关键考虑因素,并且读操作远远多于写操作,可以考虑使用其他同步机制,如 读写锁(read-write lock),它允许多个线程同时读取,但在写入时仍然保证互斥。 然而,这仍然需要仔细设计以避免潜在的死锁和性能问题。对于简单的用例或者写操作较为频繁的情况,使用互斥锁通常是最直接和安全的方法。

4、C 创建两个线程 读写一个全局变量:

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

// 全局变量
int shared_data = 0;

// 互斥锁
pthread_mutex_t mutex;

// 读取全局变量的线程函数
void* reader(void* arg) {
    int data;
    pthread_mutex_lock(&mutex);
    data = shared_data;
    pthread_mutex_unlock(&mutex);
    printf("Reader thread read data: %d\n", data);
    return NULL;
}

// 修改全局变量的线程函数
void* writer(void* arg) {
    pthread_mutex_lock(&mutex);
    shared_data = *(int*)arg;
    pthread_mutex_unlock(&mutex);
    printf("Writer thread wrote data: %d\n", shared_data);
    return NULL;
}

int main() {
    pthread_t reader_thread, writer_thread;
    int new_data = 42;

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Failed to initialize mutex");
        return EXIT_FAILURE;
    }

    // 创建读取线程
    if (pthread_create(&reader_thread, NULL, reader, NULL) != 0) {
        perror("Failed to create reader thread");
        return EXIT_FAILURE;
    }

    // 创建写入线程
    if (pthread_create(&writer_thread, NULL, writer, (void*)&new_data) != 0) {
        perror("Failed to create writer thread");
        return EXIT_FAILURE;
    }

    // 等待线程结束
    pthread_join(reader_thread, NULL);
    pthread_join(writer_thread, NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return EXIT_SUCCESS;
}

http://www.kler.cn/a/441865.html

相关文章:

  • Face2face:非深度学习时代如何进行实时的三维人脸重建
  • 从CRUD到高级功能:EF Core在.NET Core中全面应用(三)
  • MongoDB vs Redis:相似与区别
  • 大模型GUI系列论文阅读 DAY2续:《一个具备规划、长上下文理解和程序合成能力的真实世界Web代理》
  • 基于ESP32+VUE+JAVA+Ngnix的一个小型固件编译系统
  • 国产编辑器EverEdit -重复行
  • 每天40分玩转Django:Django缓存系统
  • 探索:为什么数组数据后端确要求前端传递,拼接的字符呢
  • 乳腺癌多模态诊断解释框架:CNN + 可解释 AI 可视化
  • 基于MNE的EEGNet 神经网络的脑电信号分类实战(附完整源码)
  • CAD xy坐标标注(跟随鼠标位置实时移动)——C#插件实现
  • dify智能体系列:selenium有啥好玩的?
  • 如何为IntelliJ IDEA配置JVM参数
  • springboot中Controller内文件上传到本地以及阿里云
  • 【Prompt Engineering】2.迭代优化
  • 【附源码】Electron Windows桌面壁纸开发中的 CommonJS 和 ES Module 引入问题以及 Webpack 如何处理这种兼容
  • 判题机的开发(代码沙箱、三种模式、工厂模式、策略模式优化、代理模式)
  • 单片机:实现蜂鸣器数码管的显示(附带源码)
  • Numpy基本介绍
  • Leetcode打卡:形成目标字符串需要的最少字符串数II
  • 如何在 Linux 服务器上部署 Pydio Cells 教程
  • STM32F407ZGT6-UCOSIII笔记7:优先级反转现象
  • 【图形渲染】【Unity Shader】【Nvidia CG】有用的参考资料链接
  • Composer指定php版本执行(windows)
  • git branch -r(--remotes )显示你本地仓库知道的所有 远程分支 的列表
  • Hadoop是什么?Hadoop介绍