【问题标题】:C - Pthreads mutex and general headachesC - Pthreads 互斥和一般头痛
【发布时间】:2010-11-25 12:00:55
【问题描述】:

大家好,我想知道是否有人可以提供一点帮助。

我一直在尝试自学 pthreads,然后使用互斥锁让线程一起运行并使用相同的结构,同时不会读取和写入不良数据。

我现在的问题是,

从我的线程函数中,如果我调用一个可能类似于以下内容的辅助函数:

void foo(void *arg)
{
  Bar *bar = arg;
  pthread_mutex_lock(&mutex);
  bar->something = 1;
  pthread_mutex_unlock(&mutex);
}

上面的这个辅助方法似乎没有“更新”结构。

但如果我在线程函数中运行相同的代码,完全相同的 4 行代码,那么这似乎可以工作。

我做错了什么?或者我该如何解决这个问题?如果有人也能提供一些阅读材料,那就完美了。

编辑:对不起,我的代码中有错字。

这是我用于结构的实际代码。

typedef struct {
    char *buffer[CAR_PARK_SIZE];       
    char *arrival_time[CAR_PARK_SIZE]; 
    int  keep_running;           
    int  size;          
 int  index;     
 } CarStorage;

typedef struct {
 CarStorage parks;
 CarStorage queue;
 int busy;
 } CarPark;

pthread_mutex_t mutex;

void addCar(char *car, void *arg)
{
 CarPark *_cp = arg;
 pthread_mutex_lock(&mutex);
 printf("Trying to increase size\n");
 _cp->parks.size = _cp->parks.size+1;
 pthread_mutex_unlock(&mutex);
}

如果 addCar 中相同的行在线程函数中,它会增加大小,如果它在这个辅助函数中,它不会。

这里是调用代码

void *carpark_t(void *arg)
{
    CarPark *_cp = arg; 
    while (_cp->parks.keep_running)
    {

        if (_cp->queue.size > 0)
        {

            addCar(_cp->queue.buffer[_cp->queue.index % MAX_QUEUE], &_cp);
            sleep(1);
        }
        else
        {
            printf("[C] no cars in queue\n");
            sleep(5);
        }
    }

}

【问题讨论】:

  • 您发布的代码无效(bar 不是指针,但它使用起来像一个)。当我们不得不猜测您的代码实际上是什么样子时,很难诊断您的问题。请发布您的实际代码。
  • @Employed - 你不能说bar 是或不是任何东西 - 如果我们在这段代码前面加上typedef struct _bar *Bar 那么bar 肯定指针。您说我们需要更多代码是正确的,但假设有关尚未发布的代码的事情是错误的。
  • 修复了这个问题,本来是 Bar *bar,添加了实际代码
  • 第一印象是线程中的 CarPark 结构存在范围问题。你能展示一下线程本身的一些细节吗?

标签: c pthreads mutex


【解决方案1】:

您在 addCar 中使用锁定的操作很好。您的问题出在您尚未发布的代码中。如果没有访问权限,我不确定您的问题是什么。我认为,我编写的以下代码按预期工作。但是,如果我不得不猜测问题出在哪里,我想您并没有传递要更新的结构,而是将其复制过来。希望这会有所帮助。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define CAR_PARK_SIZE 10
typedef struct {
    char *buffer[CAR_PARK_SIZE];
    char *arrival_time[CAR_PARK_SIZE];
    int  keep_running;
    int  size;
 int  index;
 } CarStorage;

typedef struct {
 CarStorage parks;
 CarStorage queue;
 int busy;
 } CarPark;

pthread_mutex_t mutex;

void *addCar( void *arg)
{
 CarPark *_cp = arg;
 pthread_mutex_lock(&mutex);

sleep(1);
 printf("Trying to increase size\n");
 _cp->parks.size = _cp->parks.size+1;
printf("new size: %d\n", _cp->parks.size);
 pthread_mutex_unlock(&mutex);
}
#define NUM_THREADS 5
int main()
{
        pthread_t threads[NUM_THREADS];
        int rc;
        long t;
        CarPark c;
        c.parks.size = 0;
        pthread_mutex_init(&mutex, NULL);
        for(t=0; t<NUM_THREADS; t++)
        {
                printf("In main: creating thread %ld\n", t);
                rc = pthread_create(&threads[t], NULL, addCar, (void *)&c);
                if (rc)
                {
                        printf("ERROR; return code from pthread_create() is %d\n", rc);
                        exit(-1);
                }
        }
        pthread_exit(NULL);
        return 0;
}

【讨论】:

  • 绝对是努力+1。在没有看到代码的情况下,您已经尽力而为。
【解决方案2】:

---- 被剪断,因为它不再适用并且无论如何都不起作用----

---- 又剪了一些,因为它不再适用并且无论如何都不起作用----

这是你的错误:

            addCar(_cp->queue.buffer[_cp->queue.index % MAX_QUEUE], &_cp);

&amp;_cp 传入了_cp地址,这是一个指向_cp 的指针。但是_cp 已经是一个指针,所以你传入了一个指向指针的指针。将&amp;_cp 更改为常规_cp,或将void addCar(char *car, void *arg) 更改为void addCar(char *car, void **arg)(并相应地编辑addCar())。任何一个都可以,但我推荐第一个,因为它更容易。

【讨论】:

  • ((CarPark*)arg)->parks.size = 1;好像没什么区别
  • 它们都是为了以后的功能,我已经实现了它,但只是将它剥离到基础知识以找出它为什么不起作用以及问题出在哪里。 Wall Werror 和 Wextra,根本没有提供太多帮助。我只是在用其他东西测试它时使用了 void *,你认为这可能与问题有关吗?
  • 它与问题的关系松散,不使用void * 将允许 GCC 捕获错误,但它不是直接导致问题。
  • @dekz - 我们所有人都至少发生过一次。
猜你喜欢
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2015-11-12
相关资源
最近更新 更多