如何在完成线程后继续 运行 一个进程?
How to continue running a process after completing threads?
我在尝试打印所有线程的摘要(即一组线程的总计)时卡住了。
下面的C代码运行10个线程,模拟售票代理。 运行 & 完成线程后(即售出所有门票后),我想打印代理商名单和该代理商售出的相应门票数量。然而,主进程在到达行 pthread_exit(NULL)
时立即终止(用前面的注释标记)并且代码不会 return 到 main
,它应该打印 grand总计(此块也标有注释)。
谁能告诉我代码有什么问题?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
struct ThreadArgs {
int thNum;
int *numTickets;
int *soldTickets;
sem_t *lock;
};
void *SellTickets(void *th) {
struct ThreadArgs *thArgs;
int sleepTime;
thArgs = th;
while (1) {
sleepTime = rand();
if (sleepTime % 2) {
usleep(sleepTime % 1000000);
}
sem_wait(thArgs->lock);
if (*thArgs->numTickets == 0) {
break;
}
printf("There are %3d ticket(s). Agent %d sold a ticket.\n", *thArgs->numTickets, thArgs->thNum);
(*thArgs->numTickets)--;
sem_post(thArgs->lock);
(*thArgs->soldTickets)++;
}
sem_post(thArgs->lock);
pthread_exit(NULL);
}
void runThreads(int numAgents, int numTickets, int soldTickets[]) {
struct ThreadArgs thArgs[numAgents];
int agent;
pthread_t th[numAgents];
sem_t lock;
sem_init(&lock, 1, 1);
for (agent = 0; agent < numAgents; agent++) {
thArgs[agent].thNum = agent;
thArgs[agent].soldTickets = &soldTickets[agent];
thArgs[agent].numTickets = &numTickets;
thArgs[agent].lock = &lock;
pthread_create(&th[agent], NULL, SellTickets, &thArgs[agent]);
}
// when debugging, the process terminates here
pthread_exit(NULL);
}
int main() {
int agent, numAgents, numTickets, soldTickets[10];
numAgents = 10;
numTickets = 150;
for (agent = 0; agent < numAgents; agent++) {
soldTickets[agent] = 0;
}
runThreads(numAgents, numTickets, soldTickets);
// the process never executes the following block
for (agent = 0; agent < numAgents; agent++) {
printf("Agent %d sold %d ticket(s).\n", agent, soldTickets[agent]);
}
return 0;
}
pthread_exit()
退出一个线程,即使是 "main"-线程。
如果 main()
结束,所有其他线程也会关闭。
由于 "main"-thread 需要做一些最后的日志记录,它应该等到所有产生的线程都结束。
要在 runThreads()
中完成此操作,请替换对
的调用
pthread_exit(NULL);
通过循环为 pthread_create()
返回的所有 PThread-ID 调用 pthread_join()
。
您还想为所有 pthread*()
调用添加错误检查,就像您应该对返回任何相关信息的每个函数调用所做的那样,例如指示 failure 调用.
我在尝试打印所有线程的摘要(即一组线程的总计)时卡住了。
下面的C代码运行10个线程,模拟售票代理。 运行 & 完成线程后(即售出所有门票后),我想打印代理商名单和该代理商售出的相应门票数量。然而,主进程在到达行 pthread_exit(NULL)
时立即终止(用前面的注释标记)并且代码不会 return 到 main
,它应该打印 grand总计(此块也标有注释)。
谁能告诉我代码有什么问题?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
struct ThreadArgs {
int thNum;
int *numTickets;
int *soldTickets;
sem_t *lock;
};
void *SellTickets(void *th) {
struct ThreadArgs *thArgs;
int sleepTime;
thArgs = th;
while (1) {
sleepTime = rand();
if (sleepTime % 2) {
usleep(sleepTime % 1000000);
}
sem_wait(thArgs->lock);
if (*thArgs->numTickets == 0) {
break;
}
printf("There are %3d ticket(s). Agent %d sold a ticket.\n", *thArgs->numTickets, thArgs->thNum);
(*thArgs->numTickets)--;
sem_post(thArgs->lock);
(*thArgs->soldTickets)++;
}
sem_post(thArgs->lock);
pthread_exit(NULL);
}
void runThreads(int numAgents, int numTickets, int soldTickets[]) {
struct ThreadArgs thArgs[numAgents];
int agent;
pthread_t th[numAgents];
sem_t lock;
sem_init(&lock, 1, 1);
for (agent = 0; agent < numAgents; agent++) {
thArgs[agent].thNum = agent;
thArgs[agent].soldTickets = &soldTickets[agent];
thArgs[agent].numTickets = &numTickets;
thArgs[agent].lock = &lock;
pthread_create(&th[agent], NULL, SellTickets, &thArgs[agent]);
}
// when debugging, the process terminates here
pthread_exit(NULL);
}
int main() {
int agent, numAgents, numTickets, soldTickets[10];
numAgents = 10;
numTickets = 150;
for (agent = 0; agent < numAgents; agent++) {
soldTickets[agent] = 0;
}
runThreads(numAgents, numTickets, soldTickets);
// the process never executes the following block
for (agent = 0; agent < numAgents; agent++) {
printf("Agent %d sold %d ticket(s).\n", agent, soldTickets[agent]);
}
return 0;
}
pthread_exit()
退出一个线程,即使是 "main"-线程。
如果 main()
结束,所有其他线程也会关闭。
由于 "main"-thread 需要做一些最后的日志记录,它应该等到所有产生的线程都结束。
要在 runThreads()
中完成此操作,请替换对
pthread_exit(NULL);
通过循环为 pthread_create()
返回的所有 PThread-ID 调用 pthread_join()
。
您还想为所有 pthread*()
调用添加错误检查,就像您应该对返回任何相关信息的每个函数调用所做的那样,例如指示 failure 调用.