c - 多线程信号量程序

标签 c multithreading pointers semaphore

我花了好几个小时试图解决这个问题,但我完全被困住了。该程序应该启动 6 个线程。一些线程开始的地方,其他线程结束的地方。 现在,我正在尝试让一个线程(线程 0)执行。 大写锁定注释显示了我添加代码和犯错误的地方。我在这里的主要斗争是处理指针。任何人都可以给我任何指示(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 用于 C/C++ 代码)。

让我们继续解决您的问题。据我所知,主要问题似乎是您基本上是在比较指向苹果的指针和指向香蕉的指针(换句话说,您在错误的位置使用了错误的指针类型)。

为确保对函数等的调用是正确的,请务必查找您不熟悉的函数的 API 文档(例如:pthread_createsem_initsem_waitsem_postpthread_cond_signal ).

如您所见,pthread_cond_signal 不接受 sem_t* 作为参数,因此您不能将一个参数传递给它并期望它起作用。下面是一个示例程序,显示了如何使用信号量。

首先,创建一个新线程,立即进入等待状态。一旦主线程完成从 0 到 150 的计数,它将发布(“解锁”)信号量并允许第二个线程完成其执行。

#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 中并使用以下方式编译和链接:

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 中并使用以下方式编译和链接:

gcc -o cond -pthread -Os -Wall cond.c

请注意此示例中整洁条件的工作原理。您可以使用它们等待任何表达式(= 条件)变为真。条件变为真后继续正常执行。

如果您需要更多帮助,请随时在评论中提问。祝你好运,结合上面的例子来修复你的程序。

关于c - 多线程信号量程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28421643/

相关文章:

c++ - C++中的指针和内存分配

c++ - 错误 : "Undefined reference to operator<<(std::ostream&, Dogs const&)"

c - 修改在 C 中作为指针传递的结构

c# - Csharp 线程在一个完成而不等待加入时启动新线程

c++ - 因shared_ptr而崩溃

java - 如何在线程和 GUI 之间进行通信

.net - 同步锁的种类

c - 打印值数组的十六进制表示

c - 获取数组输入时出现段错误

c - 如何将输出格式化为 6 列?