我有一个要求,首先我必须制作以下过程树: here
我已成功完成此操作,但此后,我还必须在进程P8中创建5个线程(在另一个任务中必须以给定的方式进行同步),并在进程P4中创建6个线程。这时的主要任务是以这种方式同步来自P8和P4的某些线程:来自P4的线程1必须在来自P8的线程1之前结束,但是来自P4的线程4只能在来自P8的线程1结束之后开始(开始/结束)线程意味着我必须打印一条消息)。我尝试执行以下操作,这对我来说很有意义: 这是主程序:
#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的线程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 called\n");
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=%d\n", 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 called\n");
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已经实现,我只需要使用它们即可。
答案 0 :(得分:1)
我认为问题出在您的wait()。主叉pid8,然后等待其完成,然后再移至叉pid2(后者又叉pid4)。在pid8完成之前,Pid2无法运行;因此它们的线程无法协调。
您应该(从主要人员)开除所有三个叉子,而不是在每次叉子之后等待, 然后等待三遍。在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