【ARM&Linux】linux系统下多线程编程

【linux系统下多线程编程学习笔记代码】



  • 线程:“轻量级”的进程。
  • 与创建它的进程共享代码段,数据段
  • 拥有自己独立的栈。

注意:使用线程,编译和链接程序必须加上选项【-pthread】,使用方法见博客下面Makefile


【代码&说明】

/****************************************************************************************
* 文件名: pro.c
* 创建者: 
* 时 间: 
* 联 系: 
* 简 介: 多线程编程控制,参考API文档《Unix环境高级编程》
*****************************************************************************************/


/***********************************************************
函数学习:
    1、创建线程: int pthread_create(pthread_t *thread, 
                                    const pthread_attr_t *attr,
                                    void *(*start_routine) (void *), 
                                    void *arg);
        返回值: 成功0 失败返回错误编码
        参数一:线程id
        参数二:存储线程的属性的结构
        参数三:指明线程的入口函数
        参数四:入口函数的参数,可为NULL

    2、等待线程结束: int pthread_join(pthread_t thread, void **retval);
        参数一:要等待结束的线程id
        参数二:保存线程退出的状态,一般为NULL
        返回值:成功0,否则返回错误代码

    3、线程退出:  void pthread_exit(void *retval); 结束调用此函数的线程
        参数一:保存返回值
-------------------------------------------------------------------
线程互斥:
    【互斥锁】: 

    1、初始化:int  pthread_mutex_init(pthread_mutex_t  *mutex,  const  pthread_mutexattr_t *mutexattr);
        参数一:根据参数二的 属性初始化互斥锁
        参数二:互斥锁的属性,如果为NULL,使用默认属性
        返回值:成功0,否则返回错误代码

    2、获取: int pthread_mutex_lock(pthread_mutex_t *mutex);
        参数一: 指明要锁住的互斥锁
        返回值: 成功0,否则返回错误代码

    3、释放锁: int pthread_mutex_unlock(pthread_mutex_t *mutex);
        参数一: 指明要解开的互斥锁
        返回值: 成功0,否则返回错误代码   

    4、注销互斥锁:  int pthread_mutex_destroy(pthread_mutex_t *mutex);
        参数一:要删除的互斥锁
        返回值: 成功0,否则返回错误代码   
-----------------------------------------------------------------------


【综合实例】:
    一位老师让学生去扫雪,老师充当主进程,学生充当线程2,班长充当线程1,两个人需要扫20此才能够扫完一条小路。
    但是目前扫把只有一个,只有在其中一个人休息的时候另一个能才能扫雪,所以扫把是共享资源。

************************************************************/
#include "mytype.h"


#define PTHREAD_COUNT 2

static unsigned int clean_snow_cnt = 0;
pthread_mutex_t mulock;     //互斥锁

void delay()
{
    int i,k;
    for(i=0; i<10000; i++)
        for(k=0; k<10000; k++)
            ;
}

void *stu1_opertion()
{
    int cnt;
    int res;

    DEBUG_INFO("I am stu1 .\n");
    for(cnt=0; cnt<10; cnt++)
    {

        pthread_mutex_lock(&mulock);        //加锁
        ++clean_snow_cnt;
        pthread_mutex_unlock(&mulock);      //释放互斥锁

        DEBUG_INFO("[stu1]-> clean snow count = %d \n", clean_snow_cnt);
        sleep(1);
    }
    DEBUG_INFO("student 1 clean snow end .\n");

    //线程退出
    pthread_exit(&res);
    if(res != 0)
    {
        DEBUG_ERROR("pthread_exit-> stu1 failed .\n ");
    }
    return 0;
}

void *stu2_opertion()
{
    int cnt;
    int res;

    DEBUG_INFO("I am stu2 .\n");

    for(cnt=0; cnt<10; cnt++)
    {

        pthread_mutex_lock(&mulock);        //加锁
        ++clean_snow_cnt;
        pthread_mutex_unlock(&mulock);      //释放互斥锁

        DEBUG_INFO("[stu2]-> clean snow count = %d \n", clean_snow_cnt);
        sleep(1);
    }
    DEBUG_INFO("student 2 clean snow end .\n");

    //线程退出
    pthread_exit(&res);
    if(res != 0)
    {
        DEBUG_ERROR("pthread_exit-> stu2 failed .\n ");
    }
    return 0;
}

int main()
{
    int res;        //保存返回值
    int count;
    pthread_t stu_thread[PTHREAD_COUNT];


    // 初始化互斥锁
    res = pthread_mutex_init(&mulock,NULL);
    if(res != 0)
    {
        DEBUG_ERROR("mutex lock init failed .\n");
        exit(EXIT_FAILURE);
    }

    // 1、创建学生线程
    if( (res=pthread_create(&stu_thread[0], NULL, stu1_opertion, NULL)) ==0 )
    {
        DEBUG_INFO("creat stu1 successful .\n");
    }
    // 2、创建学生线程2
    if( (res=pthread_create(&stu_thread[1], NULL, stu2_opertion, NULL)) == 0)
    {
        DEBUG_INFO("creat stu2 successful .\n");
    }

    // 3.等待学生线程扫雪结束
    for(count=0; count<PTHREAD_COUNT; count++)
    {
        res = pthread_join(stu_thread[count], NULL);
        if(res != 0)
        {
            DEBUG_WARNING("pthread_join-> stu %d failed , error code : %d\n", count+1, res);
        }
    }

    // 删除互斥锁
    res = pthread_mutex_destroy(&mulock);
    if(res != 0)
    {
        DEBUG_ERROR("pthread_mutex_destroy failed, error code : %d", res);
    }
    return 0;
}
/****************************************************************************************
* 文件名: mytype.h
* 创建者: Kun
* 联 系: [email protected]
* 简 介: linux常用类型定义
* 最后修改时间: 2018/2/14 16:46
*****************************************************************************************/

#ifndef _MYTYPE_H_
#define _MYTYPE_H_

//--------------------------< 预添加头文件包含 >----------------------//

#define USE_TIME 0

#define USE_SIGNAL 0
#define USE_SHARE_MEMORY 0
#define USE_SEMAPHORE 0
#define USE_MSG_QUEUE 0
#define USE_FILE_CTL 0
#define USE_THREAD 1
//-------------------------------< end ----------------------------//


//---------------------------< includes >---------------------------//
// c标准库头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 信号使用相关头文件
#if USE_SIGNAL
#include <sys/signal.h>
#endif // USE_SIGNAL

// 信号量操作相关头文件
#if USE_SEMAPHORE
#include <sys/sem.h>
#include <sys/ipc.h>
#endif // USE_SEMAPHORE

// 共享内存操作相关头文件
#if USE_SHARE_MEMORY
#include <sys/shm.h>
#endif // USE_SHARE_MEMORY

// 消息队列相关头文件
#if USE_MSG_QUEUE
    #if !USE_SEMAPHORE
        #include <sys/ipc.h>
    #endif
#include <sys/msg.h>
#endif // USE_MSG_QUEUE

// 系统调用式文件编程头文件
#include <fcntl.h>

// 该文件所定义的接口通常都是大量针对系统调用的封装,
// 如 fork、pipe 以及各种 I/O 原语(read、write、close 等等)。
#include <unistd.h>

// linux系统中类型定义相关头文件
#include <sys/types.h>

// 文件状态,是unix/linux系统定义文件状态所在的伪标准头文件。
#if USE_FILE_CTL
#include <sys/stat.h>
#endif // USE_FILE_CTL

// 时间编程相关头文件
#if USE_TIME
#include <sys/time.h>
#endif // USE_TIME


// 线程相关头文件
#if USE_THREAD
#include <pthread.h>
#endif // USE_THREAD
//-------------------------< includes end >-------------------------//


// bool类型定义
#ifndef bool
typedef unsigned int bool;
#endif
enum
{
    true = 1,
    false = !true
};

// 常用无符号数据类型定义
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;

//----------------------< 调试信息输入相关宏定义 >----------------------//
#define DEBUG_INFO(...) printf("Info: "); printf(__VA_ARGS__)
#define DEBUG_ERROR(...) printf("Error: "); printf(__VA_ARGS__)
#define DEBUG_WARNING(...) printf("Warning: "); printf(__VA_ARGS__)
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
//------------------------------------------------------------------//

// 信号量使用封装结构
#if USE_SEMAPHORE
typedef struct sem_use SEM_USE;
struct sem_use
{
    int semid;
    key_t key;
    struct sembuf sops;
};
#endif // USE_SEMAPHORE

// 共享内存使用封装结构
#if USE_SHARE_MEMORY
typedef struct shmem_use SHMEM_USE;
struct shmem_use
{
    int shmid;
    key_t key;
};

#define BUF_SIZE 1024*1 //共享内存大小
typedef struct shmem_area SHMEM_AREA;
struct shmem_area
{
    bool isnull;
    char data[BUF_SIZE];
};

#endif // USE_SHARE_MEMORY

// 消息队列使用封装结构
#if USE_MSG_QUEUE
typedef struct msg_queue_use MSG_QUEUE_USE;
struct msg_queue_use{
    key_t key;
    int msgid;
};
#endif // USE_MSG_QUEUE


#endif // _TYPE_H_



【结果】

【Makefile】

这里写图片描述

【运行结果】

这里写图片描述


end

猜你喜欢

转载自blog.csdn.net/qq153471503/article/details/79325783