多线程信号量程序
Multithreaded semaphore program
我花了好几个小时试图解决这个问题,但我完全被困住了。该程序应该启动 6 个线程。一些线程开始的地方,其他线程结束的地方。 现在,我正在尝试让一个线程(线程 0)执行。 caps lock 注释显示了我添加代码和犯错误的地方。我在这里的主要斗争是处理指针。谁能给我指点一下(ha..ha.. :c )?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define SHARED 1
sem_t sem[6];
struct threadargs
{
int id; /* thread number */
int sec; /* how many sec to sleep */
int signal[6]; /* which threads to signal when done */
};
void *tfunc(void *arg)
{
int i;
struct threadargs *targs=arg;
sem_wait(sem); //WAIT FOR OWN SEMAPHORE
printf("Thread %d is running\n", targs->id);
sleep(targs->sec);
printf("Thread %d is completed and may wake others..\n", targs->id);
for(i=0; i<6; i++) //ITERATE OVER signal_ARRAY &
{ //WAKE THREAD NUMBER i IF
if(targs->signal[i] == 1) //signal[i] IS 1
pthread_cond_signal(&sem[i]);
}
}
int main(void)
{
int i, j;
struct threadargs *targs[6];
pthread_t tid[6];
for(i=0; i<6; i++)
{
targs[i] = (struct threadargs*) malloc(sizeof(struct threadargs));
for(j=0; j<6; j++)
{ targs[i]->signal[j]=0; }
}
targs[0]->id=1;
targs[0]->sec=1;
targs[0]->signal[1]=1;
targs[0]->signal[4]=1;
sem[0] = 0; //INITIALIZE THREAD'S SEMAPHORE TO 0 or 1
pthread_create(targs[0], NULL, tfunc, NULL) // START THREAD
for(i=0; i<6; i++)
pthread_join(tid[i], NULL);
return 0;
}
好的。首先,我建议您重新审视一下您的编码风格。这当然是非常主观的,我不会说你的不好,但我花了一段时间才弄明白(如果你真的想知道,我推荐 Linux coding style for C/C++代码)。
让我们继续解决您的问题。据我所知,主要问题似乎是你基本上是在比较指向苹果的指针和指向香蕉的指针(换句话说,你在错误的地方使用了错误的指针类型)。
为确保对函数等的调用是正确的,请务必查看 API 文档以了解您不熟悉的函数(示例:pthread_create, sem_init, sem_wait, sem_post, pthread_cond_signal)。
如您所见,pthread_cond_signal 不接受 sem_t* 作为参数,因此您不能将一个参数传递给它并期望它起作用。您将在下面找到一个显示如何使用信号量的示例程序。
首先,创建一个新线程,立即进入等待状态。一旦主线程完成从 0 到 150 的计数,它将 post ('unlock') 信号量并允许第二个线程完成其执行。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t sem_thread_one;
static pthread_t thread_one_data;
static int x;
static void *tfunc(void *arg)
{
sem_wait(&sem_thread_one);
printf("Thread 1 is running. The value of x is %i\n", x);
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sem_thread_one, 0 /* don't share between processes */, 0);
if(pthread_create(&thread_one_data, NULL, &tfunc, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
while(x < 150) {
x++;
}
sem_post(&sem_thread_one);
if(pthread_join(thread_one_data, NULL)) {
fprintf(stderr, "Could not join threads, exiting!\n");
return -EXIT_FAILURE;
}
sem_destroy(&sem_thread_one);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
保存在文件中 sem.c 并编译 & link 使用:
gcc -Wall -Os -pthread -o sem_test sem.c
现在是第二个示例,但现在使用 pthread_cond_t。该程序的功能有点类似,它等待计数器达到一定数量。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
static pthread_t thread_one_data, thread_two_data;
static volatile int x, y, idx = 10;
static int count = 1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
static void *cond_test_wait(void *arg)
{
pthread_mutex_lock(&mutex);
while(count < 10) {
printf("Waiting for `count < 10' to become true\n");
pthread_cond_wait(&condition, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Test wait thread finished. Value of count: %i\n", count);
return NULL;
}
static void *cond_test_signal(void *arg)
{
while(count < 10) {
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* do more intelligent things here */
count++;
pthread_mutex_unlock(&mutex);
}
printf("Test signal thread finished\n");
return NULL;
}
int main(int argc, char **argv)
{
if(pthread_create(&thread_one_data, NULL, &cond_test_wait, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
if(pthread_create(&thread_two_data, NULL, &cond_test_signal, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
pthread_join(thread_one_data, NULL);
pthread_join(thread_two_data, NULL);
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
保存在文件中 cond.c 并编译 & link 使用:
gcc -o cond -pthread -Os -Wall cond.c
请注意此示例中整洁条件的工作方式。您可以使用它们等待任何表达式(= 条件)变为真。条件成立后继续正常执行。
如果您需要更多帮助,请随时在评论中提问。祝你好运,结合上面的例子来修复你的程序。
我花了好几个小时试图解决这个问题,但我完全被困住了。该程序应该启动 6 个线程。一些线程开始的地方,其他线程结束的地方。 现在,我正在尝试让一个线程(线程 0)执行。 caps lock 注释显示了我添加代码和犯错误的地方。我在这里的主要斗争是处理指针。谁能给我指点一下(ha..ha.. :c )?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define SHARED 1
sem_t sem[6];
struct threadargs
{
int id; /* thread number */
int sec; /* how many sec to sleep */
int signal[6]; /* which threads to signal when done */
};
void *tfunc(void *arg)
{
int i;
struct threadargs *targs=arg;
sem_wait(sem); //WAIT FOR OWN SEMAPHORE
printf("Thread %d is running\n", targs->id);
sleep(targs->sec);
printf("Thread %d is completed and may wake others..\n", targs->id);
for(i=0; i<6; i++) //ITERATE OVER signal_ARRAY &
{ //WAKE THREAD NUMBER i IF
if(targs->signal[i] == 1) //signal[i] IS 1
pthread_cond_signal(&sem[i]);
}
}
int main(void)
{
int i, j;
struct threadargs *targs[6];
pthread_t tid[6];
for(i=0; i<6; i++)
{
targs[i] = (struct threadargs*) malloc(sizeof(struct threadargs));
for(j=0; j<6; j++)
{ targs[i]->signal[j]=0; }
}
targs[0]->id=1;
targs[0]->sec=1;
targs[0]->signal[1]=1;
targs[0]->signal[4]=1;
sem[0] = 0; //INITIALIZE THREAD'S SEMAPHORE TO 0 or 1
pthread_create(targs[0], NULL, tfunc, NULL) // START THREAD
for(i=0; i<6; i++)
pthread_join(tid[i], NULL);
return 0;
}
好的。首先,我建议您重新审视一下您的编码风格。这当然是非常主观的,我不会说你的不好,但我花了一段时间才弄明白(如果你真的想知道,我推荐 Linux coding style for C/C++代码)。
让我们继续解决您的问题。据我所知,主要问题似乎是你基本上是在比较指向苹果的指针和指向香蕉的指针(换句话说,你在错误的地方使用了错误的指针类型)。
为确保对函数等的调用是正确的,请务必查看 API 文档以了解您不熟悉的函数(示例:pthread_create, sem_init, sem_wait, sem_post, pthread_cond_signal)。
如您所见,pthread_cond_signal 不接受 sem_t* 作为参数,因此您不能将一个参数传递给它并期望它起作用。您将在下面找到一个显示如何使用信号量的示例程序。
首先,创建一个新线程,立即进入等待状态。一旦主线程完成从 0 到 150 的计数,它将 post ('unlock') 信号量并允许第二个线程完成其执行。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t sem_thread_one;
static pthread_t thread_one_data;
static int x;
static void *tfunc(void *arg)
{
sem_wait(&sem_thread_one);
printf("Thread 1 is running. The value of x is %i\n", x);
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sem_thread_one, 0 /* don't share between processes */, 0);
if(pthread_create(&thread_one_data, NULL, &tfunc, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
while(x < 150) {
x++;
}
sem_post(&sem_thread_one);
if(pthread_join(thread_one_data, NULL)) {
fprintf(stderr, "Could not join threads, exiting!\n");
return -EXIT_FAILURE;
}
sem_destroy(&sem_thread_one);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
保存在文件中 sem.c 并编译 & link 使用:
gcc -Wall -Os -pthread -o sem_test sem.c
现在是第二个示例,但现在使用 pthread_cond_t。该程序的功能有点类似,它等待计数器达到一定数量。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
static pthread_t thread_one_data, thread_two_data;
static volatile int x, y, idx = 10;
static int count = 1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
static void *cond_test_wait(void *arg)
{
pthread_mutex_lock(&mutex);
while(count < 10) {
printf("Waiting for `count < 10' to become true\n");
pthread_cond_wait(&condition, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Test wait thread finished. Value of count: %i\n", count);
return NULL;
}
static void *cond_test_signal(void *arg)
{
while(count < 10) {
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* do more intelligent things here */
count++;
pthread_mutex_unlock(&mutex);
}
printf("Test signal thread finished\n");
return NULL;
}
int main(int argc, char **argv)
{
if(pthread_create(&thread_one_data, NULL, &cond_test_wait, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
if(pthread_create(&thread_two_data, NULL, &cond_test_signal, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
pthread_join(thread_one_data, NULL);
pthread_join(thread_two_data, NULL);
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
保存在文件中 cond.c 并编译 & link 使用:
gcc -o cond -pthread -Os -Wall cond.c
请注意此示例中整洁条件的工作方式。您可以使用它们等待任何表达式(= 条件)变为真。条件成立后继续正常执行。
如果您需要更多帮助,请随时在评论中提问。祝你好运,结合上面的例子来修复你的程序。