我想同時限制N個行程(作為引數引入),但是總是有N個以上的檔案要處理。每個檔案一個行程。一次只有 N 個行程正在處理。我知道程式必須做什么,但不知道如何實作它。
很抱歉,如果我解釋得不夠好,我會回答所有需要的細節。在 FreeBSD 中使用 C 代碼
for (int i = 3; i < argc; i ) {
fflush(NULL);
if((pid_son = fork()) < 0){
printf("Error");
exit(-1);
}
else if(pid_son == 0){
}
}
uj5u.com熱心網友回復:
目前尚不清楚您是否希望 o/s 強制執行限制,也不清楚如果代碼遇到該限制(如果fork()呼叫失敗)將執行什么操作。但是,您可以安排運行命令,直到達到程式員或用戶(而不是 o/s)施加的限制,然后等待其中一個完成,然后再啟動另一個。
下面是一些應該適用于大多數 POSIX 系統的 C 代碼。它在我的 GitHub 上的SOQ(堆疊溢位問題)存盤庫中作為numproc19.csrc /so-1974-7644子目錄中的檔案提供。
numproc19.c- 洗掉評論
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <string.h>
enum { MAX_KIDS = 4 };
enum { DEF_TASKS = 20 };
static _Noreturn void be_childish(int tasknum)
{
srand(getpid());
struct timespec nap = { .tv_sec = rand() % 5, .tv_nsec = (rand() % 1000) * 1000000 };
int millisecs = nap.tv_nsec / 1000000;
printf("PID ] (PPID ]): Task - - dozing %d.%.3d\n",
getpid(), getppid(), tasknum, (int)nap.tv_sec, millisecs);
nanosleep(&nap, 0);
printf("PID ] (PPID ]): Task - - done\n", getpid(), getppid(), tasknum);
exit(tasknum);
}
static size_t dead_kid(pid_t corpse, size_t nkids, pid_t *kids)
{
for (size_t i = 0; i < nkids; i )
{
if (kids[i] == corpse)
{
kids[i] = kids[--nkids];
return nkids;
}
}
printf("PID ] exited but was not a known child\n", corpse);
return nkids;
}
static int cmp_pid(const void *vp1, const void *vp2)
{
pid_t v1 = *(pid_t *)vp1;
pid_t v2 = *(pid_t *)vp2;
return (v1 > v2) - (v1 < v2);
}
static void print_kids(size_t nkids, pid_t *kids)
{
qsort(kids, nkids, sizeof(kids[0]), cmp_pid);
printf("Kids (%zu):", nkids);
for (size_t i = 0; i < nkids; i )
printf(" ]", kids[i]);
putchar('\n');
}
int main(void)
{
pid_t kids[MAX_KIDS];
size_t nkids = 0;
setvbuf(stdout, NULL, _IOLBF, 0);
for (size_t task = 0; task < DEF_TASKS; task )
{
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "failed to fork(): (%d) %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
if (pid == 0)
be_childish(task);
kids[nkids ] = pid;
printf("Kid: ]; Number of kids: %2zu\n", pid, nkids);
print_kids(nkids, kids);
if (nkids >= MAX_KIDS)
{
int status;
int corpse = waitpid(-1, &status, 0);
if (corpse < 0)
break;
printf("Child ] exited with status 0x%.4X\n", corpse, status);
nkids = dead_kid(corpse, nkids, kids);
}
}
int corpse;
int status;
while (nkids > 0 && (corpse = waitpid(-1, &status, 0)) > 0)
{
printf("Child ] exited with status 0x%.4X\n", corpse, status);
nkids = dead_kid(corpse, nkids, kids);
print_kids(nkids, kids);
}
return 0;
}
該be_childish()函式執行所需的任何實際作業。在這里,它報告自己的存在并休眠 0-5 秒范圍內的隨機時間。在生產代碼中,它要么運行程式中的一個函式,要么運行一個執行任何需要的命令。
該main()函式跟蹤它啟動了哪些行程,一旦達到限制,它就會等待行程完成。它認識到它可能有它不知道的孩子并干凈地處理他們(報告他們的終止并繼續他們的存在)。
樣品運行
Kid: 23402; Number of kids: 1
Kids (1): 23402
Kid: 23403; Number of kids: 2
Kids (2): 23402 23403
PID 23402 (PPID 23401): Task 0 - dozing 4.632
Kid: 23404; Number of kids: 3
Kids (3): 23402 23403 23404
PID 23403 (PPID 23401): Task 1 - dozing 1.881
Kid: 23405; Number of kids: 4
Kids (4): 23402 23403 23404 23405
PID 23404 (PPID 23401): Task 2 - dozing 3.130
PID 23405 (PPID 23401): Task 3 - dozing 0.379
PID 23405 (PPID 23401): Task 3 - done
Child 23405 exited with status 0x0300
Kid: 23406; Number of kids: 4
Kids (4): 23402 23403 23404 23406
PID 23406 (PPID 23401): Task 4 - dozing 2.628
PID 23403 (PPID 23401): Task 1 - done
Child 23403 exited with status 0x0100
Kid: 23407; Number of kids: 4
Kids (4): 23402 23404 23406 23407
PID 23407 (PPID 23401): Task 5 - dozing 4.877
PID 23406 (PPID 23401): Task 4 - done
Child 23406 exited with status 0x0400
Kid: 23408; Number of kids: 4
Kids (4): 23402 23404 23407 23408
PID 23408 (PPID 23401): Task 6 - dozing 1.479
PID 23404 (PPID 23401): Task 2 - done
Child 23404 exited with status 0x0200
Kid: 23409; Number of kids: 4
Kids (4): 23402 23407 23408 23409
PID 23409 (PPID 23401): Task 7 - dozing 3.728
PID 23408 (PPID 23401): Task 6 - done
Child 23408 exited with status 0x0600
Kid: 23410; Number of kids: 4
Kids (4): 23402 23407 23409 23410
PID 23410 (PPID 23401): Task 8 - dozing 0.977
PID 23402 (PPID 23401): Task 0 - done
Child 23402 exited with status 0x0000
Kid: 23411; Number of kids: 4
Kids (4): 23407 23409 23410 23411
PID 23411 (PPID 23401): Task 9 - dozing 2.226
PID 23410 (PPID 23401): Task 8 - done
Child 23410 exited with status 0x0800
Kid: 23412; Number of kids: 4
Kids (4): 23407 23409 23411 23412
PID 23412 (PPID 23401): Task 10 - dozing 4.475
PID 23407 (PPID 23401): Task 5 - done
Child 23407 exited with status 0x0500
Kid: 23413; Number of kids: 4
Kids (4): 23409 23411 23412 23413
PID 23413 (PPID 23401): Task 11 - dozing 1.724
PID 23411 (PPID 23401): Task 9 - done
PID 23409 (PPID 23401): Task 7 - done
Child 23411 exited with status 0x0900
Kid: 23414; Number of kids: 4
Kids (4): 23409 23412 23413 23414
Child 23409 exited with status 0x0700
Kid: 23415; Number of kids: 4
Kids (4): 23412 23413 23414 23415
PID 23414 (PPID 23401): Task 12 - dozing 3.973
PID 23415 (PPID 23401): Task 13 - dozing 0.222
PID 23415 (PPID 23401): Task 13 - done
Child 23415 exited with status 0x0D00
Kid: 23416; Number of kids: 4
Kids (4): 23412 23413 23414 23416
PID 23416 (PPID 23401): Task 14 - dozing 2.824
PID 23413 (PPID 23401): Task 11 - done
Child 23413 exited with status 0x0B00
Kid: 23418; Number of kids: 4
Kids (4): 23412 23414 23416 23418
PID 23418 (PPID 23401): Task 15 - dozing 1.322
PID 23418 (PPID 23401): Task 15 - done
Child 23418 exited with status 0x0F00
Kid: 23419; Number of kids: 4
Kids (4): 23412 23414 23416 23419
PID 23419 (PPID 23401): Task 16 - dozing 3.571
PID 23416 (PPID 23401): Task 14 - done
Child 23416 exited with status 0x0E00
Kid: 23420; Number of kids: 4
Kids (4): 23412 23414 23419 23420
PID 23420 (PPID 23401): Task 17 - dozing 0.820
PID 23412 (PPID 23401): Task 10 - done
Child 23412 exited with status 0x0A00
Kid: 23421; Number of kids: 4
Kids (4): 23414 23419 23420 23421
PID 23421 (PPID 23401): Task 18 - dozing 2.069
PID 23420 (PPID 23401): Task 17 - done
Child 23420 exited with status 0x1100
Kid: 23422; Number of kids: 4
Kids (4): 23414 23419 23421 23422
PID 23422 (PPID 23401): Task 19 - dozing 4.318
PID 23414 (PPID 23401): Task 12 - done
Child 23414 exited with status 0x0C00
PID 23421 (PPID 23401): Task 18 - done
Child 23421 exited with status 0x1200
Kids (2): 23419 23422
PID 23419 (PPID 23401): Task 16 - done
Child 23419 exited with status 0x1000
Kids (1): 23422
PID 23422 (PPID 23401): Task 19 - done
Child 23422 exited with status 0x1300
Kids (0):
uj5u.com熱心網友回復:
因為您詢問了如何通過將引數傳遞給您的程式來限制 FreeBSD 作業系統的行程,所以一個答案是使用cpuset與給您的程式的引數相同的實用程式:
$ NPROC=4
$ cpuset -l 0-${NPROC} myProgram ${NPROC}
另一種解決方案是使用rctl. 另一種解決方案是簡單地使用ulimit -u ${NPROC} ....
我必須指出,argc您使用的不是引數,而是提供給程式的引數數量。如果你想訪問一個引數,你必須使用argv.
但是,如果我正確理解您想做什么,那么您似乎將argc其用作作為引數給出的檔案數。在這種情況下,我不確定這是實作目標的最佳方式,因為論點可能是錯誤的、不可讀的等等……所以行程的數量。
如果您想在 FreeBSD 下以編程方式限制行程數,有很多方法可以做到:通過 FreeBSD cpuset,或者簡單地使用POSIX pthread_affinity_np功能。
在這種情況下,你必須向SO提供一個問題來解釋你真正想做什么。在其他情況下,網路將提供大量有關如何使用它的示例。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/534354.html
