c - 如何等待线程完成工作,其中由c中的clone创建的线程?

标签 c multithreading wait waitpid

我尝试等待主函数,直到线程完成其工作。但 main 函数完成工作并退出。我认为因为线程在变量中没有正确的指针/值。(计数和步骤)

有人知道在这种情况下如何正确使用 waitpid/wait 吗?

我的代码:

#define _GNU_SOURCE
#include <stdio.h>
#include <inttypes.h> /* for PRIu64 and uint64_t */
/* you'll need further includes */
#include <sched.h>
#include <stdlib.h>
#include "tally.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define STACK_SIZE 32768
#define THREADS 2
struct clone_args{
        uint64_t steps;
        uint64_t* tally;

};
int incHelper(void* arg){
        struct clone_args *args = (struct clone_args*)arg;
        uint64_t steps= args->steps;
        uint64_t* tally = args->tally;
        increment(tally,steps);
        (void) arg;
        (void) tally;
        (void) steps;
        exit(2);
        return 0;
}

int main ()
{
        uint64_t N = 10000000;
        uint64_t tally = 1;
        tally_init();
        int thread_pid[THREADS];
        int status;
        for(int i= 0; i<THREADS;i++){
                void *child_stack = malloc(STACK_SIZE);
                struct clone_args *arguments = malloc(sizeof(struct clone_args));
                arguments->steps = N;
                arguments->tally = &tally;
                void* arg = (void*) &arguments;
                thread_pid[i] = clone(incHelper, child_stack+STACK_SIZE,CLONE_VM, arg);
                pid_t pid = waitpid(thread_pid[i],&status,SIGCHLD);
                printf("C-PID [%d]\n", thread_pid[i]);
                (void) pid;
        }

        tally_clean();
        printf( "\nTally is %" PRIu64 "\n", tally );
        (void) N;
        (void) thread_pid;
        (void) tally;
        (void) status;
        printf("\n MAIN PROGRAMM END\n");
        return 0;
}

增量函数:

/* modify this function to achieve correct parallel incrementation */
void  increment ( uint64_t *tally, uint64_t steps )
{
        printf("\nTALLY: %"PRIu64"\n",*tally);
        printf("STEPS: %"PRIu64"\n",steps);
        for( uint64_t i = 0; i < steps; i++ )
        {
                *tally += 1;
        }
        return;

}

运行代码后得到的结果:

C-PID [29819]
C-PID [29820]

Tally is 1

 MAIN PROGRAMM END
root@...(~/Downloads/asst3/asst3-clone)$
TALLY: 0
STEPS: 140714329004032

TALLY: 888309
STEPS: 140714329004032

代码应该使用两个线程递增一个变量。为了避免临界区问题,我应该使用信号量。但这是另一个练习。首先练习使用clone()函数创建两个线程。我不明白,如果clone()的标志是错误的,或者我的代码是完全错误的。我是编程语言 C 的新手。

过去 12 个小时我都在使用 Google 进行搜索。

感谢您的每一个回答:)。

抱歉英语不好。

问候

最佳答案

默认情况下,clone()ed 进程不会向父进程发出有关其结束的信号。

如果您希望向父级发出有关子级结束的信号,则需要在对传递的第三个参数进行 clone() 或操作时显式传递要在其末尾发送的信号。

如果您使用SIGCHLD,则照常使用waitpid()

在后一种情况下,克隆并等待,如下所示:

  thread_pid[i] = clone(incHelper, child_stack+STACK_SIZE, CLONE_VM | SIGCHLD, arg);
  pid_t pid = waitpid(thread_pid[i], &status, 0);

如果您想使用在子端发送的另一个信号,例如 SIGUSR1,您需要使用选项 将其告知 waitpid() __WCLONE:

  thread_pid[i] = clone(incHelper, child_stack+STACK_SIZE, CLONE_VM | SIGUSR1, arg);
  pid_t pid = waitpid(thread_pid[i], &status, __WCLONE);

这个

void* arg = (void*) &arguments;

获取参数的地址。由于 arguments 已经是所需结构的地址,因此应该是:

void * arg = arguments;

注意:作为主线程 waitpid(),让 clone()ed 线程在下一次调用 clone() 之前完成>,没有并行处理increment()

关于c - 如何等待线程完成工作,其中由c中的clone创建的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20596922/

相关文章:

c - 使用 strtok,适用于一个文件,但不适用于另一个文件

将字符数组复制到另一个而不复制换行符

c# - 等待时发生 StaleElementReferenceException

c - 如何通过 C 预处理器打印磅/哈希?

有人可以解释一下这段涉及 free() 的代码实际上做了什么吗

c# - 如何确定线程在哪个 CPU 上运行?

java - Java多线程基本问题

java - int[] 在 Java 和 C++ 之间共享?

protractor - 如何等待任何元素出现在 Protractor 中

wait - 如何替换 Cypress 中的显式等待调用?