假设您不知道mutex_locks并且您不允许在程序中使用全局变量,如果返回成功的变量,您可以做什么来停止所有正在运行的pthread?
例如,您有一个传递给包含以下内容的pthread的数据结构:
typedef struct {
char * string1; //info from argv[1]
char * string2; //info from argv[2]
int id; //thread id
} dataStruct;
在main.c中创建pthread时,你可以这样创建它们:
dataStruct dataStr[nbThread]; //array of dataStructs for each thread
pthread_t tabThread[nbThread]; //Pointers for thread 1
for (int i = 0; i < nbThread; ++i) { //initiation of threads...
dataStr[i].string1 = argv[1];
pthread_create(&tabThread[i], NULL, thread, (void *)&dataStr[i]); //create pthreads and
}
for (int i = 0; i < nbThread; ++i) {
pthread_join(tabThread[i], (void**)&(ptr[i])); //join threads
//printf("\n return value from thread[%d] is [%d]\n",i, *ptr[i]);
}
现在其中一个线程找到了您希望实现的内容,如何让所有线程同时停止?
我可以在struct中指向一个指向main中的变量的指针,一旦线程成功就可以将其更改为true吗?
我可以使用pthreads的返回值以某种方式阻止它们吗?
我对指针的理解有点困难。任何帮助表示赞赏。
答案 0 :(得分:0)
这是如何使用POSIX线程实现您的目标:
#include <unistd.h>
#include <stdbool.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 10
pthread_mutex_t cv_mutex;
pthread_cond_t notification_cv;
pthread_t threads[NUM_THREADS];
bool allfinished = false;
void *worker(void *arg) {
/* Allow cancellation, */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/* and get canceled at any time, not just at cancellation points: */
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
int loop = 0;
while (true) {
printf("iteration %d\n", loop);
++loop;
/* Do some "work": */
;
/* We specifically assume the only shared state
* is the condition variable, and that the workers
* share NO OTHER STATE.
* If they do, adjust the critical section accordingly,
* perhaps with a 2nd mutex.
*/
pthread_mutex_lock(&cv_mutex);
if (loop > 5) { /* Simulate "work end" */
allfinished = true;
pthread_cond_broadcast(¬ification_cv);
pthread_mutex_unlock(&cv_mutex);
pthread_exit(NULL);
}
pthread_mutex_unlock(&cv_mutex);
}
pthread_exit(NULL);
}
void *master(void *t) {
/* Lock mutex and wait for signal. */
pthread_mutex_lock(&cv_mutex);
/* Loop because a thread might be awoken from its
* waiting state even though no thread signalled
* the condition variable:
*/
while (!allfinished)
pthread_cond_wait(¬ification_cv, &cv_mutex);
printf("master: woken up.\n");
/* Unlocking the mutex allows workers to signal the condition variable again,
* but this is irrelevant as we're heading for end-of-life:
*/
pthread_mutex_unlock(&cv_mutex);
for (size_t i = 0; i < NUM_THREADS - 1; ++i) {
pthread_cancel(threads[i]);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
pthread_attr_t attr;
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&cv_mutex, NULL);
pthread_cond_init(¬ification_cv, NULL);
/* For portability, explicitly create threads in a joinable state: */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
/* Keep a separate `master` thread, which may be doing other bookkeeping: */
pthread_t s;
pthread_create(&s, &attr, master, NULL);
for(size_t i = 0; i < sizeof threads / sizeof *threads; ++i) {
if (!pthread_create (&threads[i], &attr, worker, NULL) ) {
printf("worker %zu created\n", i);
}
}
/* Wait for all threads to complete. This will not wait forever because the master
* thread will cancel all of the workers:
*/
for (size_t i = 0; i < sizeof threads / sizeof *threads; ++i) {
pthread_join(threads[i], NULL);
printf("worker %zu done\n", i);
}
pthread_join(s, NULL);
printf("master done\n");
/* Clean up and exit */
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&cv_mutex);
pthread_cond_destroy(¬ification_cv);
pthread_exit(NULL);
}
答案 1 :(得分:-1)
我还不能评论,所以我会回复:
我认为您可以简单地使用main中定义的布尔值,并将其作为引用/指针传递给您的线程。
然后,当你的一个线程结束时,它必须更改此变量值以通知所有其他线程。因此,他们必须在其流程循环中检查此变量的状态,以便从中断。
如果使用C11和_Atomic关键字,那么对布尔值的这些操作应该没有并发/数据竞争问题(由@EOF表示高)#。
最后,你的循环调用pthread_join
将使你的程序等到每个线程都干净地返回。
答案 2 :(得分:-3)
所以我最终找到了答案。它比我想象的要简单得多。
所以在我的主要内容中我创造了一个&#34;标志&#34;变量如此:
int flag = 0;
然后在我的结构中添加了以下指针:
int * ptrTrouve; //ptr on address of flag in main.c
然后在创建所有pthread时,在传递pthread_create参数中的结构之前,我让ptrTrouve指向该标志的地址。我是这样做的
for (int i = 0; i < nbThread; ++i) { //initiation of threads...
dataStr[i].id = i; //thread ID in appropriate struct
dataStr[i].ptrTrouve = &flag; //where the value of flag is stored
pthread_create(&tabThread[i], NULL, thread, (void *)&dataStr[i]); //create pthreads and
}
最后在我的帖子中,当函数同时运行时,它们会永久验证是否:
*(dataStr.ptrTrouve) == 0
如果其中一个线程成功,它们会改变标志的值,如下所示:
*(dataStr.ptrTrouve) = 1;
当每个线程不断监视标志的值(*(dataStr.ptrTrouve))时,它们都可以同时运行。一旦标志改变,就会发生这种情况:
if(*(dataStr.ptrTrouve) == 1){ //if successful
pthread_exit(NULL);
}
我希望这个解决方案可以在将来帮助其他人。