You need to enable JavaScript to run this app. 如何使用fork和waitpid将C程序remover_ruido处理拆分为16个进程
优惠活动
大模型
产品
解决方案
定价
更多

如何使用fork和waitpid将C程序remover_ruido处理拆分为16个进程

多进程拆分去噪任务实现方案

原有实现问题

你当前的代码没有做任务拆分,16个子进程都会全量执行整个数组的去噪逻辑,同一份计算重复执行16次,完全达不到并行提速的效果。
多进程场景和你之前做多线程拆分的思路完全一致:都是把总任务拆成多份,每个执行单元只处理自己负责的部分。你这里已经用malloc_pshared分配了跨进程共享的内存,子进程对数组的修改父进程可以直接感知,不需要额外做进程间通信传结果,适配成本很低。

核心修改逻辑

  1. 把总样本数n_amost平均拆成16份,总长度不能被16整除时,最后一个进程负责处理剩余的样本
  2. 每个子进程仅调用remover_ruido处理自己所属区间的样本,不需要处理全量数据
  3. 所有子进程执行结束后父进程再继续后续逻辑

完整修改后代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <string.h>
#include <math.h>
#include <sys/wait.h>
#include <unistd.h>

#define NMIN 4000
const int NPROCESSES = 16;

double mytime();
void *malloc_pshared(size_t size);      // 分配进程间共享内存
void remover_ruido(short *dados_out, short *dados_in, int nelem);

int main(int argc, char *argv[])
{
    int n_amost;

    if (argc != 2 || (n_amost = atoi(argv[1])) < NMIN) {
        printf("语法: \"%s N\", N 不能小于 %d\n", argv[0], NMIN);
        exit(1);
    }

    short *amostras_in = (short *) malloc_pshared(sizeof(short) * n_amost);

    if (amostras_in == NULL) {
        exit(1);
    }
    else {
        for (int i = 0; i < n_amost; ++i)
            amostras_in[i] = i * 1.0;
    }

    short *amostras_out = (short *) malloc_pshared(sizeof(short) * n_amost);

    if (amostras_out == NULL)
        exit(1);

    double t0 = mytime();

    pid_t pids[16];
    int chunk_size = n_amost / NPROCESSES;
    int remainder = n_amost % NPROCESSES;

    for (int i = 0; i < NPROCESSES; i++) {
        pids[i] = fork();
        if (pids[i] == 0) {
            int start = i * chunk_size;
            int process_count = (i == NPROCESSES - 1) ? chunk_size + remainder : chunk_size;
            remover_ruido(amostras_out + start, amostras_in + start, process_count);
            exit(0);
        }
    }

    for (int i = 0; i < NPROCESSES; i++) {
        waitpid(pids[i], NULL, 0);
    }

    printf("执行时间: %f (s)\n", mytime() - t0);

    return 0;
}

double mytime() {
   struct timeval tp;
   struct timezone tzp;

   gettimeofday(&tp,&tzp);
   return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
}

 void *malloc_pshared(size_t size){
      return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED| MAP_ANONYMOUS, -1, 0);
}

void remover_ruido(short *dados_out, short *dados_in, int nelem)
{
    for (int i = 0; i != nelem; ++i)
        dados_out[i] = sqrt(dados_in[i] * dados_in[i]);
}

注意事项

因为每个子进程处理的数组区间完全独立,不会出现多个进程写入同一个内存地址的情况,不需要额外加锁保证并发安全。

内容的提问来源于stack exchange,提问作者António Bezerra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 21:06:08