zoukankan      html  css  js  c++  java
  • 简单多线程编程中的切换问题(os-hw4)

    写一个 2 线程的程序:

    首先生成一个从 1 到 1000 万的整数数组,然后用两个线程分别计算数组奇数部分和偶数部分的和,并打印出总的和。(采用 pthread API )

    #include <stdio.h>
    #include <pthread.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/time.h>
    #include <sys/syscall.h>
    #include <unistd.h>
    #include <stdlib.h>
    #define N 10000000
    #define STEP 2
    
    long int integer[N];
    
    void *sumf(void *t)
    {
        extern long int integer[N];
        int ini = *(int *)t;
        if (integer[ini] % STEP)
            printf("odd sum");
        else
            printf("even sum");
        long int s = 0;
        for (int i = ini; i < N; i += STEP)
        {
            s = s + integer[i];
        }
        printf(": %ld	", s);
    }
    
    int main()
    {
        // array of integers
        extern long int integer[N];
        for (int i = 0; i < N; i++)
            integer[i] = i + 1;
        // sample output
        long int s_spl = 0;
        for (int i = 0; i < N; i += STEP)
            s_spl += integer[i];
        printf("sample:	odd sum: %ld", s_spl);
        s_spl = 0;
        for (int i = 1; i < N; i += 2)
            s_spl += integer[i];
        printf("	even sum: %ld
    ", s_spl);
    
        // 2 threads
        printf("2 threads:
    	");
        pthread_t th1, th2;
        // time1
        struct timeval t0, t1;
        time_t sec0;
        suseconds_t msec0;
        gettimeofday(&t0, NULL);
    
        int para0 = 0, para1 = 1;
        pthread_create(&th1, NULL, sumf, (void *)&para0);
        pthread_create(&th1, NULL, sumf, (void *)&para1);
        pthread_join(th1, NULL);
        pthread_join(th2, NULL);
        // time2
        gettimeofday(&t1, NULL);
        sec0 = t1.tv_sec - t0.tv_sec;
        msec0 = t1.tv_usec - t0.tv_usec;
        printf("
    	(glibc) time used:%ld.%ldms
    ", sec0 * 1000, msec0);
        return 0;
    }
    

    编译执行的结果:

    $ gcc hw4.c -lm -O3 -g -o hw4 -lpthread # 在最后链接pthread的动态库
    $ ./hw4    
    sample: odd sum: 25000000000000 even sum: 25000005000000
    2 threads:
            odd sumeven sum: 25000000000000 : 25000005000000
            (glibc) time used:0.4862ms
    

    可以发现最后输出格式略奇怪,检查 sumf 函数,发现它的结构大致为:if-calc()-prtf(res),由于 pthread_create 产生的线程可能在执行中随机切换(即线程内有序,线程间随机),因此有可能执行完 th1 的 if 段后切换到 th2 执行,从而使输入格式不符合预期(在程序上并没有毛病)。

    为了改善这种情况,注意到 printf 提供的是封装的内核态函数的用户态接口,因此考虑把 if 的 print 和 res 的print合并使用 printf,新的 sumf 如下:

    void *sumf(void *t)
    {
        extern long int integer[N];
        int ini = *(int *)t;
          // 把求和放在前面
        long int s = 0;
        for (int i = ini; i < N; i += STEP)
        {
            s = s + integer[i];
        }
          // 合并输出想要的结果
        if (integer[ini] % STEP)
            printf("odd sum: %ld	", s);
        else
            printf("even sum: %ld	", s);
    }
    

    得到的结果即修正为:

    $ gcc hw4.c -lm -O3 -g -o hw4 -lpthread
    $ ./hw4
    sample: odd sum: 25000000000000 even sum: 25000005000000
    2 threads:
            odd sum: 25000000000000 even sum: 25000005000000
            (glibc) time used:0.4958ms
    

    该修改的效用得到验证。

  • 相关阅读:
    使用 Helm【转】
    部署 Helm【转】
    Helm 架构【转】
    Why Helm?【转】
    用 ConfigMap 管理配置【转】
    js argument实参集合与局部变量、参数关系
    js 定时器
    JVM的调优
    Java异常,以及finally不会执行的情况
    Java绑定
  • 原文地址:https://www.cnblogs.com/ria2020/p/13785339.html
Copyright © 2011-2022 走看看