linux多线程编程(四)

Linux多线程编程(四)攻略

前言

本文将讲解在Linux环境下进行多线程编程的基本概念、操作方法和注意事项,通过示例代码演示实现多线程的一些常见用法。

基础知识

线程的创建和销毁

线程是轻量级的进程,一个进程可以包含多个线程。线程的创建和销毁都是通过pthread库中的函数来完成的:

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);

int pthread_join(pthread_t thread, void **retval);

int pthread_cancel(pthread_t thread);
  • pthread_create函数用于创建一个线程,并将它开始执行的起始点指定为start_routine(这个起始点函数必须是void* func(void*)形式的函数指针)。该函数会返回一个线程ID,存放在thread中,可以通过该线程ID对线程进行操作。
  • pthread_join函数用于等待一个线程结束,并获取它的返回值(如果有的话)。如果线程在执行pthread_exit或返回语句时传入了一个指针,那么这个指针就作为retval的值传递回来。
  • pthread_cancel函数用于向线程发送一个取消信号,线程可以在任意时刻响应这个信号并结束运行。

线程的同步

多个线程在共享同一个资源时会出现竞态问题,这时需要使用线程同步机制来保证数据的正确性。常用的线程同步机制有:

  • 互斥锁:即mutex,提供对共享资源的互斥访问,防止多个线程同时读写资源。
  • 条件变量:即cond,用于线程之间的通信和唤醒。
  • 信号量:即sem,用于线程之间的通信和控制并发。

线程的并发

在多线程编程中,线程的并发性是非常重要的,可以通过以下几种方式来提高线程的并发性:

  • 减小锁的粒度
  • 使用无锁的数据结构
  • 增加CPU核心数
  • 使用协程等更高级别的并发方式

实战

示例一:使用线程池进行并发处理

下面的示例是使用线程池对多个任务进行并发处理的代码。

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

typedef struct job {
    void *(*function)(void *);
    void *argument;
    struct job *next;
} job_t;

typedef struct {
    job_t *head;
    job_t *tail;
    int job_count;
    int thread_count;
    pthread_mutex_t mutex;
    pthread_cond_t condition;
} threadpool_t;

threadpool_t *threadpool_create(int thread_count)
{
    threadpool_t *pool = (threadpool_t *)malloc(sizeof(threadpool_t));
    pthread_mutex_init(&pool->mutex, NULL);
    pthread_cond_init(&pool->condition, NULL);
    pool->head = NULL;
    pool->tail = NULL;
    pool->job_count = 0;
    pool->thread_count = thread_count;
    for (int i = 0; i < thread_count; i++) {
        pthread_t worker;
        pthread_create(&worker, NULL, threadpool_worker, pool);
        pthread_detach(worker);
    }
    return pool;
}

int threadpool_add_job(threadpool_t *pool, void *(*function)(void *), void *argument)
{
    job_t *new_job = (job_t *)malloc(sizeof(job_t));
    new_job->function = function;
    new_job->argument = argument;
    new_job->next = NULL;
    pthread_mutex_lock(&pool->mutex);
    if (pool->head == NULL) {
        pool->head = new_job;
        pool->tail = new_job;
    } else {
        pool->tail->next = new_job;
        pool->tail = new_job;
    }
    pool->job_count++;
    pthread_mutex_unlock(&pool->mutex);
    pthread_cond_signal(&pool->condition);
    return 0;
}

void *threadpool_worker(void *arg)
{
    threadpool_t *pool = (threadpool_t *)arg;
    while (1) {
        pthread_mutex_lock(&pool->mutex);
        while (pool->head == NULL)
            pthread_cond_wait(&pool->condition, &pool->mutex);
        job_t *job = pool->head;
        pool->head = pool->head->next;
        if (pool->head == NULL)
            pool->tail = NULL;
        pool->job_count--;
        pthread_mutex_unlock(&pool->mutex);
        job->function(job->argument);
        free(job);
    }
}

void threadpool_destroy(threadpool_t *pool)
{
    pthread_mutex_lock(&pool->mutex);
    job_t *current = pool->head;
    while (current != NULL) {
        job_t *next = current->next;
        free(current);
        current = next;
    }
    pthread_mutex_unlock(&pool->mutex);
    pthread_mutex_destroy(&pool->mutex);
    pthread_cond_destroy(&pool->condition);
    free(pool);
}

void *task(void *arg)
{
    int n = *(int *)arg;
    printf("Task %d is running\n", n);
    sleep(1);
    printf("Task %d is done\n", n);
    return NULL;
}

int main()
{
    threadpool_t *pool = threadpool_create(4);
    int n = 10;
    for (int i = 0; i < n; i++)
        threadpool_add_job(pool, task, &i);
    sleep(10);
    threadpool_destroy(pool);
    return 0;
}

该代码实现了一个简单的线程池,可以对多个任务进行并发处理。

示例二:使用互斥锁保护共享资源

下面的示例是使用互斥锁保护共享资源的代码。

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

#define THREAD_COUNT 10

int counter = 0;
pthread_mutex_t mutex;

void *increment(void *arg)
{
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&mutex);
        counter++;
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main()
{
    pthread_t threads[THREAD_COUNT];
    pthread_mutex_init(&mutex, NULL);
    for (int i = 0; i < THREAD_COUNT; i++)
        pthread_create(&threads[i], NULL, increment, NULL);
    for (int i = 0; i < THREAD_COUNT; i++)
        pthread_join(threads[i], NULL);
    printf("Counter = %d\n", counter);
    pthread_mutex_destroy(&mutex);
    return 0;
}

该代码使用互斥锁保护了一个共享变量,避免了多个线程同时读写该变量的产生竞态问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:linux多线程编程(四) - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案

    Python对任意数据和曲线进行拟合并求出函数表达式有以下三种常见的解决方案: 多项式拟合: 多项式拟合是一种最简单的拟合方法,其实现思路是在已有的数据点上,通过构建一个多项式,来逼近已知的函数。在Python中,使用numpy库中的polyfit函数来实现多项式拟合。具体步骤如下: import numpy as np import matplotlib.…

    C 2023年5月22日
    00
  • 解决python subprocess参数shell=True踩到的坑

    下面就为你详细讲解如何解决Python subprocess参数shell=True踩到的坑,包括具体步骤和示例说明。 什么是subprocess? 在Python中,subprocess是一个标准库,用于管理子进程。通过subprocess模块,可以启动一个新的进程,并与它进行通信,从而能够执行操作系统级别的任何命令。 shell=True的作用 在使用P…

    C 2023年5月22日
    00
  • C++实现学校运动会管理系统

    实现C++学校运动会管理系统可以按照以下步骤进行: 1. 确定系统需求和功能 首先需要确定学校运动会管理系统的具体需求和功能,包括但不限于以下几点: 学校各个学院和班级的参赛信息管理(包括报名、成绩等); 不同项目的成绩管理和排名显示; 按照学院、班级等分类统计成绩和排名; 系统安全性和用户权限管理。 2. 构建系统框架和设计数据结构 根据需求和功能,可以设…

    C 2023年5月23日
    00
  • C++实现超市商品管理系统最新版

    C++实现超市商品管理系统最新版攻略 简介 超市商品管理系统是一种管理超市商品信息、库存、进货、销售等方面的软件,通过该软件可以实现对超市商品信息的实时管理、库存信息的查询统计、进货信息的记录及管理、销售信息的记录及管理等功能。 使用C++语言实现超市商品管理系统,可以有效提高软件运行效率、增加程序的健壮性和稳定性,方便进行后期维护。 实现过程 1. 软件架…

    C 2023年5月23日
    00
  • 联想c440怎么样? 联想C440一体机拆机图解

    联想c440怎么样? 联想C440是一款款一体机电脑,它具有优秀的性能表现、大屏幕显示效果以及简约大气的外观设计等特点。以下是对C440的相关介绍: 性能表现 C440搭载了英特尔® 第三代酷睿™ 处理器,采用NVIDIA GT635显卡和4GB内存,处理速度迅速、操作稳定。同时,它还内置了1000GB的硬盘,可以存储大量的数据。 显示效果 C440采用了2…

    C 2023年5月23日
    00
  • C++学生信息管理系统

    C++学生信息管理系统攻略 简介 本文将详细讲解如何开发一款基于 C++ 的学生信息管理系统,该系统可以实现添加学生、删除学生、修改学生信息、查询学生信息等常见的学生信息管理操作。该系统可以帮助学校、班级或老师方便地管理学生信息,提高信息管理效率。 技术方案 C++语言 C++是一种高效的面向对象编程语言,具有良好的性能和可扩展性。它是学生信息管理系统的常用…

    C 2023年5月22日
    00
  • SpringMVC JSON数据交互及RESTful支持实现方法

    下面是详细讲解“SpringMVC JSON数据交互及RESTful支持实现方法”的完整攻略。 SpringMVC JSON数据交互及RESTful支持实现方法 什么是JSON JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于 JavaScript 的一个子集。JSON采用完全独立于语言的文本格式,因此可…

    C 2023年5月23日
    00
  • C语言职工管理系统设计

    C语言职工管理系统设计攻略 目录 概述 界面设计 功能设计 代码实现 示例说明 总结 1. 概述 C语言职工管理系统设计是一个基于控制台的应用程序,旨在设计一个能够管理职工信息的管理系统,方便管理员有效地管理职工信息。 本系统的主要功能包括:添加职工、显示职工、删除职工、修改职工、查找职工、排序职工等。 2. 界面设计 首先,需要针对系统的功能进行界面设计,…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部