如何等待线程完成自己的工作,在那里通过线程克隆在c? [英] How to wait for threads to finish their work, where threads created by clone in c?

查看:275
本文介绍了如何等待线程完成自己的工作,在那里通过线程克隆在c?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着等待的主要功能,直到线程完成自己的工作。但主要的功能完成其工作并退出。我想,正因为如此线程在变量不正确的指针/值。(理货和步骤)

I try to wait the main function, till the threads finish their work. But the main function finish its work and exit. I think because of that the threads has not the correct pointers/values in the variables.(tally and steps)

是否有人知道如何使用waitpid函数/在这种情况下,适当地等待?

Does someone know how to use waitpid/wait properly in this case?

我的code:

#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;

}

运行code后,我得到的结果:

The Result i got after running the code:

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

在code应该增加一个变量有两个线程。为了避免CriticalSection的问题,我应该使用信号量。但多数民众赞成在其他的运动。第一个练习它使用的clone()函数创建两个线程。我不明白,如果克隆()的标志是错的还是我的code是完全错误的。我在编程C语言新的。

The code should increment a variable with two threads. To avoid criticalsection Problem i should use semaphores. But thats an other exercise. First exercise it to use clone() function to create two threads. I dont understand, if the flags of clone() are wrong or my code is completely wrong. I am new at programming language C.

我花了与谷歌的搜索过去12小时。

I spent last 12 hours of searching with google.

我要感谢每一个答案:)

I thank for every answer :).

抱歉不好英语。

问候

推荐答案

每默认情况下,的clone()编辑过程中不通知有关其最终母公司。

Per default a clone()ed process does not signal the parent about its end.

如果您希望家长发出信号对孩子的最后,你需要explictily传递信号要在结束时发送的clone() ING或运算到3参数传递。

If you want the parent to be signaled about the child's end you need to explictily pass the signal to be sent on its end when clone()ing ORed to the 3rd parameter passed.

如果您使用 SIGCHLD 然后用 waitpid函数()如常。

If you use SIGCHLD then use waitpid() as usual.

在后一种情况下克隆并等待像这样:

In this latter case clone and wait like so:

  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

If you want to use another signal to be sent on the child's end like for example SIGUSR1 you need to tell this to waitpid() using the option __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;

需要的参数的地址。由于参数已经是所需结构的地址,它应该是:

takes the address of arguments. As arguments already is an address of the required structure, it should be:

void * arg = arguments;


请注意:由于主线程 waitpid函数() S为的clone() ED线程前完成下次调用的clone(),有并行)的处理单位(


Note: As the main thread waitpid()s for the clone()ed thread to finish before the next call to clone(), there is no parallel processing of increment()

这篇关于如何等待线程完成自己的工作,在那里通过线程克隆在c?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆