我正在尝试了解线程和信号量。我希望能够启动和停止线程。下面的一些代码创建了一个线程,然后停止,因为 semaphore 的值为 0,所以 sem_wait() 不会返回。如何更改 main()
中 semaphore
的值以便启动线程?例如,如果我使用 getchar()
输入一个字符,然后启动线程?我尝试使用sem_post()
。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
sem_t semaphore;
void threadfunc() {
printf("thread started\r\n");
while (1) {
sem_wait(&semaphore);
printf("Hello from da thread!\n");
sem_post(&semaphore);
sleep(1);
}
}
int main(void) {
// initialize semaphore, only to be used with threads in this process, set value to 1
sem_init(&semaphore, 0, 0);
pthread_t *mythread;
mythread = (pthread_t *)malloc(sizeof(*mythread));
// start the thread
printf("Starting thread, semaphore is locked.\n");
pthread_create(mythread, NULL, (void*)threadfunc, NULL);
sem_wait(&semaphore);
getchar();
//Now start the thread
return 0;
}
最佳答案
我在这里看到的问题是 main()
永远不会调用 getChar()
,因为您调用了 sem_wait()
在其中。
试试这个:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
sem_t semaphore;
void* threadfunc(void*) {
printf("thread started\r\n");
while (1) {
// Wait for main to post to the semaphore
sem_wait(&semaphore);
printf("Hello from da thread!\n");
// Post to the semaphore ourselves since main will only do one
sem_post(&semaphore);
sleep(1);
}
}
int main(void) {
pthread_t mythread;
sem_init(&semaphore, 0, 0);
// start the thread
printf("Starting thread, semaphore is locked.\n");
pthread_create(&mythread, NULL, threadfunc, NULL);
getchar();
sem_post(&semaphore);
// Wait for threadfunc to return, otherwise our program dies early.
pthread_join(&mythread, NULL);
return 0;
}
在此,threadfunc()
等待初始值为 0
的信号量。 main()
立即继续进行 getchar()
调用,之后发送信号量,允许 threadfunc()
继续进行。
这里的另一个关键是在 main()
末尾调用 pthread_join()
。这会导致 main()
在继续之前等待 threadfunc()
返回。一旦 main()
返回,无论您的线程是否完成,您的程序都将被操作系统拆除。
在这种情况下,threadfunc()
将永远运行,main()
将永远不会返回。
另请注意 threadfunc()
返回类型的更改。 pthreads 需要一个接受并返回 void* 参数的函数。您的 Actor 只是隐藏了您的函数没有正确的签名。 (感谢@mch)
关于c 如何启动一个通过更改信号量值而停止的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45213646/