关于一个互斥的问题

tianshilei1992 2012-11-06 01:09:20
在测试多线程在一个时间片可以运行次数的问题时,用到了一个全局变量main_counter,这个变量是用来保存所有的3个线程总共运行次数的,还有一个数组counter,用来保存每个进程运行次数的,最后在main函数里面对counter数组进行求和,赋值给sum。代码如下:

/*POSIX 下线程控制的实验程序残缺版*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <pthread.h>

#define MAX_THREAD 3 /* 线程的个数 */

unsigned long long main_counter, counter[MAX_THREAD];
void *thread_worker(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;

int
main(int argc, char* argv[])
{
int i, rtn, ch;
pthread_t pthread_id[MAX_THREAD] = {0}; /* 存放线程id*/
pthread_t t;

for (i = 0; i < MAX_THREAD; i++)
{
/* 在这里填写代码,用pthread_create建一个普通的线程,
线程id存入pthread_id[i],线程执行函数是thread_worker
并i作为参数传递给线程 */
pthread_create(&t, NULL, thread_worker,&i);
pthread_id[i] = t;
}
do
{
/* 用户按一次回车执行下面的循环体一次。按q退出 */
unsigned long long sum = 0;
unsigned long long tmp[MAX_THREAD];
/* 求所有线程的counter的和 */
for (i = 0; i < MAX_THREAD; i++)
{
/* 求所有counter的和 */
sum += counter[i];
printf("%llu\n ", counter[i]);
}
printf("%llu-----%llu\n", main_counter, sum);
} while ((ch = getchar()) != 'q');
return 0;
}

void
*thread_worker(void* p)
{
/*在这里填写代码,把main中的i的值传递给thread_num*/
int *thread_num = (int *)p;
for(;;)
{
/*无限循环*/
pthread_mutex_lock(&mutex1);
counter[*thread_num]++; /* 本线程的counter加一 */
main_counter++; /* 主counter 加一 */
pthread_mutex_unlock(&mutex1);
}
}

现在想通过用互斥,来达到main_counter和sum相等,在这里我产生了疑问,请教一下大家。就是我想在进行for循环求值的时候就将counter数组和main_counter锁住,不知道应该怎么实现?
并且我发现,在运行main函数的for循环时,线程都有可能被抢占,所以求得sum值和main_counter值根本不可能相等。不知道该怎么做才能实现要求?(上面红字描述)
...全文
248 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Panda_熊猫 2012-11-07
  • 打赏
  • 举报
回复
引用 4 楼 tianshilei1992 的回复:
引用 2 楼 guochanoo7 的回复: 你在获得conut[i]的值的时候线程并没有停止执行,所以如果想让sum和mainconuter相等的话,计算这两个值的时候就让线程都停下呗,最简单的方法就是在计算的过程中占用线程用到的mutex 确实!问题解决了!一共有两个问题,第一个就是只用一个互斥就ok,第二个问题是,写pthread_create函数的时候,最后一个参数的类型应该是(v……
>写pthread_create函数的时候,最后一个参数的类型应该是(void *),而不能直接取地址 原因在这里呀,所以我才在6楼加了限制条件,因为发现打印的p=3.。。。。。。。
Panda_熊猫 2012-11-07
  • 打赏
  • 举报
回复
引用 2 楼 guochanoo7 的回复:
你在获得conut[i]的值的时候线程并没有停止执行,所以如果想让sum和mainconuter相等的话,计算这两个值的时候就让线程都停下呗,最简单的方法就是在计算的过程中占用线程用到的mutex
+1
Panda_熊猫 2012-11-07
  • 打赏
  • 举报
回复
void*thread_worker(void* p)  
{
//  int *thread_num = (int *)p;     
    for(;;)    
    {   
        pthread_mutex_lock(&mutex1);    
        if( ((*(int*)p)<3) && ((*(int*)p)>= 0)) 
        {   
        counter[(*(int*)p)]++;
        //printf("p=%d\n",(*(int*)p));
        main_counter++; 
        }   
        pthread_mutex_unlock(&mutex1);    
    }   
}
加如上判断条件。
tianshilei1992 2012-11-06
  • 打赏
  • 举报
回复
引用 3 楼 User64 的回复:
for (i = 0; i < MAX_THREAD; i++) { pthread_mutex_lock(&mutex1); /* 求所有counter的和 */ sum += counter[i]; printf("%ll……
确实!问题解决了!一共有两个问题,第一个就是只用一个互斥就ok,第二个问题是,写pthread_create函数的时候,最后一个参数的类型应该是(void *),而不能直接取地址。
tianshilei1992 2012-11-06
  • 打赏
  • 举报
回复
引用 2 楼 guochanoo7 的回复:
你在获得conut[i]的值的时候线程并没有停止执行,所以如果想让sum和mainconuter相等的话,计算这两个值的时候就让线程都停下呗,最简单的方法就是在计算的过程中占用线程用到的mutex
确实!问题解决了!一共有两个问题,第一个就是只用一个互斥就ok,第二个问题是,写pthread_create函数的时候,最后一个参数的类型应该是(void *),而不能直接取地址。
User64 2012-11-06
  • 打赏
  • 举报
回复
for (i = 0; i < MAX_THREAD; i++) { pthread_mutex_lock(&mutex1); /* 求所有counter的和 */ sum += counter[i]; printf("%llu\n ", counter[i]); pthread_mutex_unlock(&mutex1); } 这里之所以用mutex1是因为保证此处不被子线程抢占,用mutex2加锁无意义
guochanoo7 2012-11-06
  • 打赏
  • 举报
回复
你在获得conut[i]的值的时候线程并没有停止执行,所以如果想让sum和mainconuter相等的话,计算这两个值的时候就让线程都停下呗,最简单的方法就是在计算的过程中占用线程用到的mutex
ouyh12345 2012-11-06
  • 打赏
  • 举报
回复
如果互斥的话,获得和释放mutex,都需要消耗cpu

69,335

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧