gpt4 book ai didi

C 代码在创建第一个 pthread (Linux) 后停止

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:32 24 4
gpt4 key购买 nike

我的代码应该多次执行 start_hydrogenstart_carbon 函数,但只从一个线程的执行输出到控制台,然后程序挂起。我想我可能错误地启动了线程。我是 C 的新手,所以如果需要其他信息,请告诉我。请注意,打印了 this line is reached 输出。

#include "main.h"

void *start_hydrogen(void *);//executes hydrogen.c
void *start_carbon(void *);//executes carbon.c

struct threadInfo {
int threadId;
};

struct threadInfo hydrogenIDs[NUM_H];
struct threadInfo carbonIDs[NUM_C];

int main() {
int semid, shmid;//semaphore memory id, shared memory id
unsigned short seminit[NUM_SEMS];//used to initialize semaphores
struct common *shared;//pointer to shared data structure
union semun semctlarg;//used to initialize semaphores

pthread_t hydrogen[NUM_H];
pthread_t carbon[NUM_C];
pthread_attr_t attr;
void *exit_status;

//Creating a set of attributes to send to the threads
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

//get semaphore memory id
if ((semid = semget(SEMKEY, NUM_SEMS, IPC_CREAT|0777)) < 0) {
perror("semget");
exit(EXIT_FAILURE);
}

printf("THE PROGRAM IS STARTING\n\n");

seminit[MUTEX] = 1;//initialize mutex semaphore count to 1
seminit[SH] = 0;//initialize hyrdrogen semaphore count to 0
seminit[SC] = 0;//initialize carbon semaphore count to 0
semctlarg.array = seminit;//set control array

//apply initialization
if ((semctl(semid, NUM_SEMS, SETALL, semctlarg)) < 0) {
perror("semctl");
exit(EXIT_FAILURE);
}

//get shared memory id
if ((shmid = shmget(SHMKEY, 1*K, IPC_CREAT|0777)) < 0) {
perror("shmget");
exit(EXIT_FAILURE);
}

//retrieve pointer to shared data structure
if ((shared = (struct common *)shmat(shmid, 0, 0)) < 0) {
perror("shmat");
exit(EXIT_FAILURE);
}

//initialize shared data structure variables
shared->waiting_H = 0;
shared->waiting_C = 0;

int retVal;//used to check return value of fork()

// spawn 20 Hydrogens
for (int i=0; i<NUM_H; i++) {
// if ((retVal = fork()) == 0) {
// hydrogen();
// fflush(stdout);
// printf("New Hydrogen process created\n");
// fflush(stdout);
// } else if (retVal < 0) {
// perror("fork");
// exit(EXIT_FAILURE);
// }
hydrogenIDs[i].threadId = i;
retVal = pthread_create(&hydrogen[i], &attr, start_hydrogen, (void*) &hydrogenIDs[i]);
if (retVal != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}

printf("this line reached\n");

// spawn 5 Carbons
for (int i=0; i<NUM_C; i++) {
// if ((retVal = fork()) == 0) {
// carbon();
// fflush(stdout);
// printf("New Hydrogen process created\n");
// fflush(stdout);
// } else if (retVal < 0) {
// perror("fork");
// exit(EXIT_FAILURE);
// }
carbonIDs[i].threadId = i;
retVal = pthread_create(&carbon[i], &attr, start_carbon, (void*) &carbonIDs[i]);
if (retVal != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}

//wait for all car processes to finish
// for (int i = 0; i < 25; ++i) {
// if (wait(0) < 0) {
// perror("wait");
// exit(EXIT_FAILURE);
// }
// }

//Wait for all the threads to finish
for(int i = 0; i < NUM_C; i++)
{
pthread_join(carbon[i], &exit_status);
}

for(int i = 0; i < NUM_H; i++)
{
pthread_join(hydrogen[i], &exit_status);
}



printf("All atoms have crossed!\n");

//delete semaphores
if (semctl(semid, NUM_SEMS, IPC_RMID, 0) < 0) {
perror("semctl");
exit(EXIT_FAILURE);
}

//delete shared memory
if (shmctl(shmid, IPC_RMID, 0) < 0) {
perror("shmctl");
exit(EXIT_FAILURE);
}

return EXIT_SUCCESS;
}

原始start_carbon()start_hydrogen() 函数

void *start_carbon(void* arg) {
execl("carbon", "carbon", 0);
perror("execl");
exit(EXIT_FAILURE);//if exec returns there was an error
}

void *start_hydrogen(void* arg) {
execl("hydrogen", "hydrogen", 0);
perror("execl");
exit(EXIT_FAILURE);//if exec returns there was an error
}

修改的start_hydrogen()start_carbon() 函数

在收到有关使用 execl() 不当的反馈后,我将 start_hydrogen()start_carbon() 函数更改为:

void *start_hydrogen(void* arg) {
struct common *shared;//pointer to shared data structure

int semid, shmid;//semaphore memory id, shared memory id

int pid = getpid();

//get semaphore memory id
if ((semid = semget(SEMKEY, NUM_SEMS, 0777)) < 0) {
perror("semget");
exit(EXIT_FAILURE);
}

//get shared memory id
if ((shmid = shmget(SHMKEY, 1*K, 0777)) < 0) {
perror("shmget");
exit(EXIT_FAILURE);
}

//get pointer to shared data structure
if ((shared = (struct common *)shmat(shmid, 0, 0)) < 0) {
perror("shmat");
exit(EXIT_FAILURE);
}

// acquire lock on mutex before accessing shared memory
semWait(semid, MUTEX);

fflush(stdout);
printf("Hydrogen atom, pid %d, arrives at barrier\n", pid);
printf("Currently %d Hydrogens and %d Carbons waiting\n", shared->waiting_H + 1, shared->waiting_C);
fflush(stdout);

// if enough C and H is waiting, continue past barrier
if (shared->waiting_H >= 3
&& shared->waiting_C >= 1) {
// release 3 H
for (int i=0; i < 3; i++) {
semSignal(semid, SH);
}
shared->waiting_H -= 3;
semSignal(semid, SC); // release 1 C
shared->waiting_C -= 1;

fflush(stdout);
printf("\nHello from %d, 1 CH4 molecule has xed the barrier\n\n", pid);
fflush(stdout);
// release lock on mutex
semSignal(semid, MUTEX);
} else {
// not enough C or H is waiting, so wait at barrier
shared->waiting_H += 1;
// relaese lock on mutex
semSignal(semid, MUTEX);
semWait(semid, SH);
}
pthread_exit(NULL);
}

void *start_carbon(void* arg) {
struct common *shared;//pointer to shared data structure

int semid, shmid;//semaphore memory id, shared memory id

int pid = getpid();

//get semaphore memory id
if ((semid = semget(SEMKEY, NUM_SEMS, 0777)) < 0) {
perror("semget");
exit(EXIT_FAILURE);
}

//get shared memory id
if ((shmid = shmget(SHMKEY, 1*K, 0777)) < 0) {
perror("shmget");
exit(EXIT_FAILURE);
}

//get pointer to shared data structure
if ((shared = (struct common *)shmat(shmid, 0, 0)) < 0) {
perror("shmat");
exit(EXIT_FAILURE);
}

// acquire lock on mutex before accessing shared memory
semWait(semid, MUTEX);

fflush(stdout);
printf("Hydrogen atom, pid %d, arrives at barrier\n", pid);
printf("Currently %d Hydrogens and %d Carbons waiting\n", shared->waiting_H + 1, shared->waiting_C);
fflush(stdout);

// if enough C and H is waiting, continue past barrier
if (shared->waiting_H >= 3
&& shared->waiting_C >= 1) {
// release 3 H
for (int i=0; i < 3; i++) {
semSignal(semid, SH);
}
shared->waiting_H -= 3;
semSignal(semid, SC); // release 1 C
shared->waiting_C -= 1;

fflush(stdout);
printf("\nHello from %d, 1 CH4 molecule has xed the barrier\n\n", pid);
fflush(stdout);
// release lock on mutex
semSignal(semid, MUTEX);
} else {
// not enough C or H is waiting, so wait at barrier
shared->waiting_H += 1;
// relaese lock on mutex
semSignal(semid, MUTEX);
semWait(semid, SH);
}
pthread_exit(NULL);
}

最佳答案

来自 execl() 的手册页,

The exec() family of functions replaces the current process image with a new process image.

The exec() functions only return if an error has occurred.

如果要用execl()调用外部程序,应该先fork()父进程,让父进程继续运行。请注意,在这种情况下,线程实际上不会执行您想要的操作。

关于C 代码在创建第一个 pthread (Linux) 后停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36584832/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com