来自C,Linux中不同过程的线程的同步



我有一个评估,起初我必须制作以下过程树:这里

我已经成功地做到了这一点,但是在此之后,我还必须在进程P8中创建5个线程(在另一个任务中必须以给定的方式同步(,而过程p4中的6个线程。此时的主要任务是以这种方式从P8和P4同步某些线程:P4的线程1必须在p8线程1之前结束,但是P4的线程4可以在P8 thread 1 end thread 1 end End End(启动/结束(之后启动(启动/结束(线程意味着我必须打印一条消息(。我尝试做以下事情,对我来说很有意义:这是主要程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "a2_helper.h"
int thread_numbers[35];
int started = 0;
int finished = 0;
int barr_count = 0;
sem_t *msem;
sem_t *sem_aux;
sem_t *sem_thd;
sem_t *sem_one;
sem_t *sem_two;
typedef struct thd_s
{
    int id;
    pthread_t thd;
    pthread_mutex_t *lock;
    pthread_cond_t *cond;
    int process_nr;
}THD;
void *thread_function_diff(void *args)
{
    THD *thd = (THD *)args;
    if (thd->process_nr == 8 && thd->id == 1)
    {
        info(BEGIN, thd->process_nr, thd->id);
        sem_wait(sem_one);
        info(END, thd->process_nr, thd->id);
        sem_post(sem_two);
    }
    else if (thd->process_nr == 4 && thd->id == 1)
    {
        info(BEGIN, thd->process_nr, thd->id);
        info(END, thd->process_nr, thd->id);
        sem_post(sem_one);
    }
    else if (thd->process_nr == 4 && thd->id == 4)
    {
        sem_wait(sem_two);
        info(BEGIN, thd->process_nr, thd->id);
        info(END, thd->process_nr, thd->id);
    }
    else
    {
        info(BEGIN, thd->process_nr, thd->id);
        info(END, thd->process_nr, thd->id);
    }
    pthread_exit(0);
}
void *thread_function_barr(void *args)
{
    THD *thd = (THD *)args;
    sem_wait(msem);
//
//    if (thd->id == 31 || thd->id == 32 || thd->id == 33 || thd->id == 34)
//    {
//        info(BEGIN, thd->process_nr, thd->id);
//        sem_post(sem_thd);
//        sem_wait(sem_aux);
//        info(END, thd->process_nr, thd->id);
//    }
//    else
//    {
//        if (thd->id == 13)
//        {
//            sem_wait(sem_thd);
//            sem_wait(sem_thd);
//            sem_wait(sem_thd);
//            sem_wait(sem_thd);
//            info(BEGIN, thd->process_nr, thd->id);
//            info(END, thd->process_nr, thd->id);
//            sem_post(sem_aux);
//            sem_post(sem_aux);
//            sem_post(sem_aux);
//            sem_post(sem_aux);
//        }
//        else
//        {
            info(BEGIN, thd->process_nr, thd->id);
            info(END, thd->process_nr, thd->id);
//        }
//    }
    sem_post(msem);
    pthread_exit(0);
}
void *thread_function(void *args)
{
    THD *thd = (THD *)args;
    pthread_mutex_lock(thd->lock);
    while (started == 0 && thd->id == 3)
    {
        pthread_cond_wait(thd->cond, thd->lock);
    }
    info(BEGIN, thd->process_nr, thd->id);
    pthread_mutex_unlock(thd->lock);
    info(END, thd->process_nr, thd->id);
    pthread_mutex_lock(thd->lock);
    if (thd->id == 3)
    {
        finished = 1;
        pthread_cond_signal(thd->cond);
    }
    pthread_mutex_unlock(thd->lock);
    pthread_exit(0);
}
void *thread_function5(void *args)
{
    THD *thd = (THD *)args;
    started = 1;
    info(BEGIN, thd->process_nr, thd->id);
    pthread_cond_signal(thd->cond);
    pthread_mutex_lock(thd->lock);
    while (finished == 0)
    {
        pthread_cond_wait(thd->cond, thd->lock);
    }
    info(END, thd->process_nr, thd->id);
    pthread_mutex_unlock(thd->lock);
    pthread_exit(0);
}
int main()
{
    init();
    info(BEGIN, 1, 0);
    sem_one = sem_open("sem_one", O_CREAT, 0644, 0);
    sem_two = sem_open("sem_two", O_CREAT, 0644, 0);
    pid_t pid2 = -1, pid3 = -1, pid8 = -1;
    pid8 = fork();
    if (pid8 == 0)
    {
        info(BEGIN, 8, 0);
        THD thds[5];
        pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
        pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
        for (int i = 4; i >= 0; i--)
        {
            thds[i].id = i + 1;
            thds[i].process_nr = 8;
            thds[i].lock = &lock;
            thds[i].cond = &cond;
            if (thds[i].id == 5)
            {
                pthread_create(&(thds[i].thd), NULL, thread_function5, &thds[i]);
            }
            else if (thds[i].id == 1)
            {
                pthread_create(&(thds[i].thd), NULL, thread_function_diff, &thds[i]);
            }
            else
            {
                pthread_create(&(thds[i].thd), NULL, thread_function, &thds[i]);
            }
        }
        for (int i = 4; i >= 0; i--)
        {
            pthread_join(thds[i].thd, NULL);
        }
        pthread_cond_destroy(&cond);
        pthread_mutex_destroy(&lock);
        info(END, 8, 0);
        exit(0);
    }
    else
    {
        wait(NULL);
    }
    pid2 = fork();
    if (pid2 == 0)
    {
        info(BEGIN, 2, 0);
        pid_t pid4 = -1, pid5 = -1, pid9 = -1;
        pid4 = fork();
        if (pid4 == 0)
        {
            info(BEGIN, 4, 0);
            THD thds[6];
            for (int i = 5; i >= 0; i--)
            {
                thds[i].id = i + 1;
                thds[i].process_nr = 4;
                thds[i].lock = NULL;
                thds[i].cond = NULL;
                pthread_create(&(thds[i].thd), NULL, thread_function_diff, &thds[i]);
            }
            for (int i = 5; i >= 0; i--)
            {
                pthread_join(thds[i].thd, NULL);
            }
            info(END, 4, 0);
            exit(0);
        }
        else
        {
            wait(NULL);
        }
        pid5 = fork();
        if (pid5 == 0)
        {
            info(BEGIN, 5, 0);
            THD thds[36];
            sem_unlink("thdsemaphore");
            sem_unlink("auxsemaphore");
            sem_unlink("barriersemaphore");
            msem = sem_open("barriersemaphore", O_CREAT, 0644, 5);
            sem_aux = sem_open("auxsemaphore", O_CREAT, 0644, 0);
            sem_thd = sem_open("thdsemaphore", O_CREAT, 0644, 0);
            pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
            for (int i = 35; i >= 0; i--)
            {
                if (i + 1 == 13)
                {
                    thread_numbers[i] = 36;
                }
                else
                {
                    thread_numbers[i] = i + 1;
                }
                thds[i].id = i + 1;
                thds[i].process_nr = 5;
                thds[i].lock = &lock;
                thds[i].cond = NULL;
                pthread_create(&(thds[i].thd), NULL, thread_function_barr, &thds[i]);
            }
            for (int i = 35; i >= 0; i--)
            {
                pthread_join(thds[i].thd, NULL);
            }
            pid_t pid6 = -1;
            pid6 = fork();
            if (pid6 == 0)
            {
                info(BEGIN, 6, 0);
                info(END, 6, 0);
                exit(0);
            }
            else
            {
                wait(NULL);
            }
            pthread_mutex_destroy(&lock);
            sem_close(sem_thd);
            sem_unlink("thdsemaphore");
            sem_close(sem_aux);
            sem_unlink("auxsemaphore");
            sem_close(msem);
            sem_unlink("barriersemaphore");
            info(END, 5, 0);
            exit(0);
        }
        else
        {
            wait(NULL);
        }
        pid9 = fork();
        if (pid9 == 0)
        {
            info(BEGIN, 9, 0);
            info(END, 9, 0);
            exit(0);
        }
        else
        {
            wait(NULL);
        }
        info(END, 2, 0);
        exit(0);
    }
    else
    {
        wait(NULL);
    }
    pid3 = fork();
    if (pid3 == 0)
    {
        info(BEGIN, 3, 0);
        pid_t pid7 = -1;
        pid7 = fork();
        if (pid7 == 0)
        {
            info(BEGIN, 7, 0);
            info(END, 7, 0);
            exit(0);
        }
        else
        {
            wait(NULL);
        }
        info(END, 3, 0);
        exit(0);
    }
    else
    {
        wait(NULL);
    }
    sem_close(sem_one);
    sem_close(sem_two);
    sem_unlink("sem_one");
    sem_unlink("sem_two");
    info(END, 1, 0);
    return 0;
}

问题是,如果我尝试这样做,则来自P8的线程1将无休止地等待信号量的许可,但是该许可是由P4的Thread 1给出的,从来没有机会运行,因为主要功能,我必须确保任何过程中的主线程都不应在任何其他线程之前结束,并且所有过程都应等待其子进程结束。

这是a2_helper.h:

#ifndef __A2_HELPER_H__
#define __A2_HELPER_H__
#define BEGIN 1
#define END 2
void init();
int info(int action, int processNr, int threadNr);
#endif

这是a2_helper.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <signal.h>
#include "a2_helper.h"
#define SEM_NAME "A2_HELPER_SEM_17871"
#define SERVER_PORT 1988
#define XSTR(s) STR(s)
#define STR(s) #s
#define CHECK(c) if(!(c)){perror("info function failed at line " XSTR(__LINE__)); break;}
int initialized = 0;
int info(int action, int processNr, int threadNr){
    int msg[6];
    int sleepTime = 0;
    int sockfd = -1;
    struct sockaddr_in serv_addr;
    sem_t *sem = SEM_FAILED;
    int err = -1;
    if(initialized == 0){
        printf("init() function not calledn");
        return -1;
    }
    do{
        CHECK((sem = sem_open(SEM_NAME, 0)) != SEM_FAILED);
        //prepare the message
        msg[0] = action;
        msg[1] = processNr;
        msg[2] = threadNr;
        msg[3] = getpid();
        msg[4] = getppid();
        msg[5] = pthread_self();
        CHECK((sockfd = socket(AF_INET, SOCK_STREAM, 0)) >= 0);
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(SERVER_PORT);
        CHECK(sem_wait(sem) == 0);
        err = -2;
        if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) >= 0){
            CHECK(write(sockfd, msg, sizeof(msg)) == sizeof(msg));
            CHECK(read(sockfd, &sleepTime, sizeof(sleepTime)) == sizeof(sleepTime));
            printf("[T] ");
        }else{
            printf("[ ] ");
        }
        printf("%s P%d T%d pid=%d ppid=%d tid=%dn", msg[0]==BEGIN?"BEGIN":" END ", msg[1], msg[2], msg[3], msg[4], msg[5]);
        CHECK(sem_post(sem) == 0);
        err = -1;
        usleep(sleepTime);
        err = 0;
    }while(0);
    if(sockfd >= 0){
        close(sockfd);
    }
    if(err==-2){
        sem_post(sem);
    }
    return err;
}
void atfork_prepare(){
    sem_t *sem = SEM_FAILED;
    do{
        CHECK((sem = sem_open(SEM_NAME, O_CREAT, 0644, 1)) != SEM_FAILED);
        CHECK(sem_wait(sem) == 0);
    }while(0);
}
void atfork_parent(){
    sem_t *sem = SEM_FAILED;
    do{
        CHECK((sem = sem_open(SEM_NAME, O_CREAT, 0644, 1)) != SEM_FAILED);
        CHECK(sem_post(sem) == 0);
    }while(0);
}
void atfork_child(){
    prctl(PR_SET_PDEATHSIG, SIGHUP);
}
void init(){
    sem_t *sem = SEM_FAILED;
    if(initialized != 0){
        printf("init() function already calledn");
        return;
    }
    do{
        pthread_atfork(atfork_prepare, atfork_parent, atfork_child);
        sem_unlink(SEM_NAME);
        CHECK((sem = sem_open(SEM_NAME, O_CREAT, 0644, 1)) != SEM_FAILED);
        initialized = 1;
    }while(0);
}

a2_helper.c和a2_helper.h已经实现了,我只需要使用它们。

我认为问题是您的wait((。主叉PID8,然后等待它完成,然后再进入fork pid2(又依次forks pid4(。PID2在PID8完成之前无法运行;因此他们的线程无法协调。

您不要等待每个叉子,而是应(从主(开火,然后等待三遍。在PID2中,您应该做同样的事情。

我不确定预期的输出是什么,但是当我更改它时,它从打印11行和悬挂到生成并退出:

[ ] BEGIN P1 T0 pid=17861 ppid=17097 tid=1351051072
[ ] BEGIN P2 T0 pid=17863 ppid=17861 tid=1351051072
[ ] BEGIN P8 T0 pid=17862 ppid=17861 tid=1351051072
[ ] BEGIN P3 T0 pid=17864 ppid=17861 tid=1351051072
[ ] BEGIN P8 T1 pid=17862 ppid=17861 tid=1308952320
[ ] BEGIN P8 T5 pid=17862 ppid=17861 tid=1342523136
[ ] BEGIN P8 T4 pid=17862 ppid=17861 tid=1334130432
[ ] BEGIN P4 T0 pid=17867 ppid=17863 tid=1351051072
[ ] BEGIN P4 T6 pid=17867 ppid=17863 tid=1342523136
[ ] BEGIN P7 T0 pid=17871 ppid=17864 tid=1351051072
[ ] BEGIN P8 T2 pid=17862 ppid=17861 tid=1317345024
[ ] BEGIN P4 T3 pid=17867 ppid=17863 tid=1317345024
[ ] BEGIN P9 T0 pid=17879 ppid=17863 tid=1351051072
[ ] BEGIN P4 T5 pid=17867 ppid=17863 tid=1334130432
[ ] BEGIN P4 T1 pid=17867 ppid=17863 tid=1300559616
[ ]  END  P4 T5 pid=17867 ppid=17863 tid=1334130432
[ ]  END  P4 T6 pid=17867 ppid=17863 tid=1342523136
[ ] BEGIN P4 T2 pid=17867 ppid=17863 tid=1308952320
[ ]  END  P7 T0 pid=17871 ppid=17864 tid=1351051072
[ ]  END  P8 T2 pid=17862 ppid=17861 tid=1317345024
[ ] BEGIN P8 T3 pid=17862 ppid=17861 tid=1325737728
[ ] BEGIN P5 T0 pid=17873 ppid=17863 tid=1351051072
[ ]  END  P4 T3 pid=17867 ppid=17863 tid=1317345024
[ ]  END  P9 T0 pid=17879 ppid=17863 tid=1351051072
[ ]  END  P4 T1 pid=17867 ppid=17863 tid=1300559616
[ ]  END  P8 T1 pid=17862 ppid=17861 tid=1308952320
[ ]  END  P4 T2 pid=17867 ppid=17863 tid=1308952320
[ ]  END  P8 T3 pid=17862 ppid=17861 tid=1325737728
[ ]  END  P3 T0 pid=17864 ppid=17861 tid=1351051072
[ ] BEGIN P5 T34 pid=17873 ppid=17863 tid=1325737728
[ ] BEGIN P5 T33 pid=17873 ppid=17863 tid=1317345024
[ ] BEGIN P5 T31 pid=17873 ppid=17863 tid=1300559616
[ ] BEGIN P4 T4 pid=17867 ppid=17863 tid=1325737728
[ ] BEGIN P5 T36 pid=17873 ppid=17863 tid=1342523136
[ ] BEGIN P5 T30 pid=17873 ppid=17863 tid=1292166912
[ ]  END  P5 T33 pid=17873 ppid=17863 tid=1317345024
[ ]  END  P5 T30 pid=17873 ppid=17863 tid=1292166912
[ ] BEGIN P5 T35 pid=17873 ppid=17863 tid=1334130432
[ ] BEGIN P5 T2 pid=17873 ppid=17863 tid=1057171200
[ ]  END  P5 T36 pid=17873 ppid=17863 tid=1342523136
[ ]  END  P5 T34 pid=17873 ppid=17863 tid=1325737728
[ ]  END  P8 T5 pid=17862 ppid=17861 tid=1342523136
[ ]  END  P8 T4 pid=17862 ppid=17861 tid=1334130432
[ ]  END  P4 T4 pid=17867 ppid=17863 tid=1325737728
[ ]  END  P5 T31 pid=17873 ppid=17863 tid=1300559616
[ ]  END  P5 T35 pid=17873 ppid=17863 tid=1334130432
[ ]  END  P4 T0 pid=17867 ppid=17863 tid=1351051072
[ ] BEGIN P5 T26 pid=17873 ppid=17863 tid=1258596096
[ ] BEGIN P5 T28 pid=17873 ppid=17863 tid=1275381504
[ ] BEGIN P5 T29 pid=17873 ppid=17863 tid=1283774208
[ ]  END  P5 T28 pid=17873 ppid=17863 tid=1275381504
[ ]  END  P5 T2 pid=17873 ppid=17863 tid=1057171200
[ ]  END  P8 T0 pid=17862 ppid=17861 tid=1351051072
[ ]  END  P5 T26 pid=17873 ppid=17863 tid=1258596096
[ ] BEGIN P5 T27 pid=17873 ppid=17863 tid=1266988800
[ ]  END  P5 T29 pid=17873 ppid=17863 tid=1283774208
[ ] BEGIN P5 T25 pid=17873 ppid=17863 tid=1250203392
[ ] BEGIN P5 T24 pid=17873 ppid=17863 tid=1241810688
[ ]  END  P5 T27 pid=17873 ppid=17863 tid=1266988800
[ ]  END  P5 T25 pid=17873 ppid=17863 tid=1250203392
[ ] BEGIN P5 T23 pid=17873 ppid=17863 tid=1233417984
[ ]  END  P5 T24 pid=17873 ppid=17863 tid=1241810688
[ ] BEGIN P5 T22 pid=17873 ppid=17863 tid=1225025280
[ ] BEGIN P5 T17 pid=17873 ppid=17863 tid=1183061760
[ ]  END  P5 T22 pid=17873 ppid=17863 tid=1225025280
[ ]  END  P5 T23 pid=17873 ppid=17863 tid=1233417984
[ ] BEGIN P5 T14 pid=17873 ppid=17863 tid=1157883648
[ ]  END  P5 T17 pid=17873 ppid=17863 tid=1183061760
[ ] BEGIN P5 T18 pid=17873 ppid=17863 tid=1191454464
[ ] BEGIN P5 T13 pid=17873 ppid=17863 tid=1149490944
[ ] BEGIN P5 T15 pid=17873 ppid=17863 tid=1166276352
[ ]  END  P5 T14 pid=17873 ppid=17863 tid=1157883648
[ ]  END  P5 T18 pid=17873 ppid=17863 tid=1191454464
[ ] BEGIN P5 T11 pid=17873 ppid=17863 tid=1132705536
[ ]  END  P5 T13 pid=17873 ppid=17863 tid=1149490944
[ ]  END  P5 T15 pid=17873 ppid=17863 tid=1166276352
[ ] BEGIN P5 T10 pid=17873 ppid=17863 tid=1124312832
[ ] BEGIN P5 T5 pid=17873 ppid=17863 tid=1082349312
[ ]  END  P5 T11 pid=17873 ppid=17863 tid=1132705536
[ ] BEGIN P5 T7 pid=17873 ppid=17863 tid=1099134720
[ ] BEGIN P5 T4 pid=17873 ppid=17863 tid=1073956608
[ ]  END  P5 T5 pid=17873 ppid=17863 tid=1082349312
[ ]  END  P5 T7 pid=17873 ppid=17863 tid=1099134720
[ ]  END  P5 T4 pid=17873 ppid=17863 tid=1073956608
[ ]  END  P5 T10 pid=17873 ppid=17863 tid=1124312832
[ ] BEGIN P5 T6 pid=17873 ppid=17863 tid=1090742016
[ ] BEGIN P5 T3 pid=17873 ppid=17863 tid=1065563904
[ ] BEGIN P5 T8 pid=17873 ppid=17863 tid=1107527424
[ ] BEGIN P5 T9 pid=17873 ppid=17863 tid=1115920128
[ ] BEGIN P5 T12 pid=17873 ppid=17863 tid=1141098240
[ ]  END  P5 T6 pid=17873 ppid=17863 tid=1090742016
[ ]  END  P5 T12 pid=17873 ppid=17863 tid=1141098240
[ ]  END  P5 T8 pid=17873 ppid=17863 tid=1107527424
[ ]  END  P5 T9 pid=17873 ppid=17863 tid=1115920128
[ ] BEGIN P5 T20 pid=17873 ppid=17863 tid=1208239872
[ ] BEGIN P5 T21 pid=17873 ppid=17863 tid=1216632576
[ ] BEGIN P5 T19 pid=17873 ppid=17863 tid=1199847168
[ ] BEGIN P5 T16 pid=17873 ppid=17863 tid=1174669056
[ ]  END  P5 T3 pid=17873 ppid=17863 tid=1065563904
[ ]  END  P5 T20 pid=17873 ppid=17863 tid=1208239872
[ ]  END  P5 T21 pid=17873 ppid=17863 tid=1216632576
[ ]  END  P5 T19 pid=17873 ppid=17863 tid=1199847168
[ ]  END  P5 T16 pid=17873 ppid=17863 tid=1174669056
[ ] BEGIN P5 T32 pid=17873 ppid=17863 tid=1308952320
[ ] BEGIN P5 T1 pid=17873 ppid=17863 tid=1048778496
[ ]  END  P5 T1 pid=17873 ppid=17863 tid=1048778496
[ ]  END  P5 T32 pid=17873 ppid=17863 tid=1308952320
[ ] BEGIN P6 T0 pid=17916 ppid=17873 tid=1351051072
[ ]  END  P6 T0 pid=17916 ppid=17873 tid=1351051072
[ ]  END  P5 T0 pid=17873 ppid=17863 tid=1351051072
[ ]  END  P2 T0 pid=17863 ppid=17861 tid=1351051072
[ ]  END  P1 T0 pid=17861 ppid=17097 tid=1351051072

相关内容

  • 没有找到相关文章

最新更新