操作系统实验——浅谈pthread库线程创建

初学操作系统对于线程的知识了解是很重要的,因此我们借用对pthread库函数的一些小运用来加深对多线程的认识。
注:本实验在linux系统下进行。

“pthread.h”头文件无法在windows平台下直接引用,需要在编译器编译过程中自行添加,笔者测试用的是pthreads-w32-2-4-0-release.exe,有兴趣的读者可自行研究这里不作扩展。


涉及到的函数有:

pthread_create //用于创建一个新的线程

//pthread_create函数原型:
#include <pthread.h>
 int pthread_create(pthread_t *restrict tidp,
               const pthread_attr_t *restrict attr,
               void *(*start_rtn)(void),
               void *restrict arg);

 Returns: 0 if OK, error number on failure
  • pthread_t *restrict tidp ,tidp是指向一个线程ID的指针。
  • const pthread_attr_t *restrict attr:线程属性设置。
  • void *(*start_rtn)(void),第三个参数是一个指向函数指针,即线程运行函数的起始地址。新创建的线程从该函数的起始地址开始运行。
  • void *restrict arg:给执行函数传递参数参数
    返回值:
    若成功则返回0,否则返回出错编号。

由 restrict修饰的指针是最初唯一对指针所指向的对象进行存取的方法,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改,保证了代码的安全性。

pthread_jion//阻塞,等待线程结束

//pthread_jion函数原型
#include <pthread.h>
int pthread_join(pthread_t thread, 
              void **retval); 
Returns: 0 if OK, error number on failure

-pthread_t thread:线程ID。
-void **retval为一个用户定义的指针,它可以用来存储被等待线程的返回值。
返回值:
若成功则返回0,否则返回出错编号。

当我们需要所有线程都结束之后再对他们的结果进行统一操作时,就需要在主函数里加入阻塞函数,等待所有线程都结束后在进行后续操作。


实例:随机生成10万个浮点数,创建4个线程分别实现2.5万个浮点数之和最后完成10万个浮点数之和。比较多线程和单线程的计算时间。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <memory.h>
#include <sys/time.h>

#define Max_Set 100000
float ssum[Max_Set];
pthread_t thread[4];
float suma=0.0;
float sumb=0.0;
float sumc=0.0;
float sumd=0.0;
float sum=0.0;

void fullssum(float a[],int length)
{
    for(int i=0;i<length;i++)
    ssum[i]=rand()/(float)(RAND_MAX/10);

}


void *thread_a(void *in)
{
    printf("i am thread_a\n");
    for(int i=0;i<Max_Set/4;i++)
    {
        suma+=ssum[i];
    }
    printf("suma=====%f\n",suma);
    pthread_exit((void *)0);
}

void *thread_b(void *in)
{
    printf("i am thread_b\n");
    for(int i=Max_Set/4;i<Max_Set/2;i++)
        {
                sumb+=ssum[i];
        }
        printf("sumb=====%f\n",sumb);

    pthread_exit((void *)0);
}

void *thread_c(void *in)
{
        printf("i am thread_c\n");
        for(int i=Max_Set/2;i<Max_Set*3/4;i++)
        {
                sumc+=ssum[i];
        }
        printf("sumc=====%f\n",sumc);

        pthread_exit((void *)0);
}

void *thread_d(void *in)
{
        printf("i am thread_d\n");
        for(int i=Max_Set*3/4;i<Max_Set;i++)
        {
                sumd+=ssum[i];
        }
        printf("sumd=====%f\n",sumd);
        pthread_exit((void *)0);
}

int main()
{
    int temp;
    struct timeval start, end1,end2;

    //用随机数填满数组
    fullssum(ssum,Max_Set);
    //初始化线程ID
    memset(&thread ,0 ,sizeof(thread));
    //获取当前时间
    gettimeofday(&start,NULL);
    if((temp=pthread_create(&thread[0],NULL,thread_a,NULL))!=0)
    printf("error in thread_a\n");
    else
    printf("thread_a creat success!\n");
    if((temp=pthread_create(&thread[1],NULL,thread_b,NULL))!=0)
        printf("error in thread_b\n");
    else
        printf("thread_b creat success!\n");
     if((temp=pthread_create(&thread[2],NULL,thread_c,NULL))!=0)
        printf("error in thread_c\n");
     else
        printf("thread_c creat success!\n");
     if((temp=pthread_create(&thread[3],NULL,thread_d,NULL))!=0)
        printf("error in thread_d\n");
     else
        printf("thread_d creat success!\n");
    for(int i=0;i<4;i++)
    {
        if(thread[0]!=0)
        {   
        pthread_join(thread[0],NULL);
        printf("thread%d come to an end\n",i+1);
        }
    }
    //等待所有线程结束计算和
    printf("RESULT1=======%f\n",suma+sumb+sumc+sumd);
    //获取当前时间
    gettimeofday(&end1,NULL);
    int time1=1000000*(end1.tv_sec-start.tv_sec)+end1.tv_usec-start.tv_usec;
    //输出多线程计算用时
    printf("time1======%d\n",time1);
    for(int j=0;j<Max_Set;j++)
    {
        sum+=ssum[j];
    }
    printf("RESULT2=======%f\n",sum);
    gettimeofday(&end2,NULL);
    int time2=1000000*(end2.tv_sec-end1.tv_sec)+end2.tv_usec-end1.tv_usec;
    //输出单线程计算用时
    printf("time2======%d\n",time2);
}

使用gcc编译pthread库程序需要加 -lpthread
例如:gcc pthread.c -o thread -lpthread

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值