C语言,Linux,线程

发布于 2021-11-12 15:55:21 字数 1282 浏览 823 评论 20

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
// repeat 100 times to mimic 100 random visits to the page
#define RPT 100
//web page visit counter
int cnt=0;
void* counter() {
int cntLocalCopy;
float r;
cntLocalCopy = cnt;
// mimicking the work of the sever in serving the page to
// the browser
r = rand() % 2000; usleep(r);
cnt = cntLocalCopy + 1;
}
int main () {
int i;
float r;
pthread_t tid[RPT];
// seed the random number sequence
srand(time(NULL));
for (i=0; i<RPT; i++) {
// mimicking the random access to the web page
r = rand() % 2000; usleep(r);
// a thread to respond to a connect from a browser
pthread_create (&tid[i], NULL, &counter, NULL);
}
// Wait till threads complete.
for (i=0; i<RPT; i++) {
pthread_join(tid[i], NULL);
}
// print out the counter value and the number of mimicked visits
// the 2 values should be the same if the program is written
// properly
printf ("cnt=%d, repeat=%dn", cnt, RPT);
}

输出:

cnt=63, repeat=100
cnt=59, repeat=100
cnt=58, repeat=100
cnt=63, repeat=100
cnt=59, repeat=100
cnt=59, repeat=100

这好像是一个关于统计网站浏览的题。但看不懂。求解读。我把程序在linux下编译不过。说没有定义'pthread_create'跟'pthread_join'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

贱贱哒 2021-11-17 14:06:19

我试了很多次输出,大概输出就在74-85之间。为什么这个值不会一直增加下去

酒几许 2021-11-17 14:06:19

你把
cntLocalCopy = cnt;这句话放到
r = 
rand
() % 2000; usleep(r);这句下面试试

回眸一笑 2021-11-17 14:06:19

把它放进去后有什么好久吗,现在程序是哪里不妥或者说是哪里有缺陷。麻烦您再跟我说一下好吗

挽清梦 2021-11-17 14:06:19

你这里的随机数基本没有起作用,我不知道你为什么在主函数里放个随机数,还在couter里也有随机数, 你可以把随机数打印出来就会发现,都是一样的,另外,在couter里对临界资源cnt的使用也没有保护。参见楼上的回答内容。可以看出,你对于多线程这块还比较陌生,应该多在这些基础上下些功夫,上面说的东西大部分都是多线程情况下基本的和常用的东西。

风透绣罗衣 2021-11-17 14:06:19

我还真不了解多线程。这个学期我才第一次接解线程。我以前学生物的,我学线程给我的感觉就是DNA在染色体上的东西。这代码是我老师给的,他意在让我们修改这个代码,让它变成更合理。可是我连这代码想干什么都不懂。

一个人的旅程 2021-11-17 14:06:19

@clverjaem

你现在的代码会出现这样的问题。假设你的代码已经调整成如下:

int cnt=0;
08	void* counter() {
09	
10	float r;
11	
12	// mimicking the work of the sever in serving the page to
13	// the browser
14	r = rand() % 2000; usleep(r);
15	cnt = cnt + 1;
16	}

上面这样已经都快了。读了就加,加了就写出。

 ld a0,[cnt]
 inc a0,a0
 st [cnt],a0

上面是对应的伪汇编,但是如果在st[cnt],a0没有被执行前,这个进程被挂起,让给别的进程操作,

那么此时,别的进程读到的,仍然是这个进程没有+1的cnt值,假设是 59.

那么新进来的进程会对cnt写60进去。而当前进程,由于重新获得CPU的控制权,继续运行,而a0里面也是60,59+1出来的。此时就出现,两个进程,均读取的是59,而均写出60的情况,此时cnt就不能反应有多少次不同进程被调用的数据。

 

 

情绪失控 2021-11-17 14:06:19

这段代码不合理的地方就在于线程不安全,也就是共享的变量没有保护。

你先读取了全局变量cnt的值,然后usleep了一小段时间,再去修改cnt的值
这中间睡眠了一段时间,有可能其他线程已经修改了cnt的值。

老师要你们改,简单的做法就是上面说的先睡再改,高级点得做法就是加锁

无声静候 2021-11-17 14:06:19

是的。我刚刚也是发现代码中有一个循环100次的。谢谢你

英雄似剑 2021-11-17 14:06:19

为什么修改后仍然没有看到效果。输出都是100。应该是可以看到增加的次数吗。因为这个代码好像是统计访问量

居里长安 2021-11-17 14:06:19

原来是这样呀。谢谢。您们都是神哥,都是编程帝。

执手闯天涯 2021-11-17 14:06:19

有没有一个代码例子是两个线程共享一个资源,并让它们列锁。也就是说求这一程序代码(C语言初学者)。thx

一个人的旅程 2021-11-17 14:06:18

因为每个线程先读cnt,然后usleep一小段时间,可能这睡眠的时间内,其他线程操作改变了cnt的值,但是睡醒后还是按原来的值+1赋值,所以每次都可能会不一样

琴流音 2021-11-17 14:06:16

应该是

gcc- o t2 t2.c -pthread

后知后觉 2021-11-17 14:06:14

是小写的L,-lpthread

gcc -o t2 t2.c -lpthread

囚你心 2021-11-17 13:58:08

还是一样不行。我的文件名为t2 gcc - t2 t2.c -Ipthread是这样吗

各自安好 2021-11-17 13:57:01

编译加上-lpthread

秉烛思 2021-11-17 13:00:24

这里头有两个这句话,一个是在main函数里的。一个是在 *counter函数里的。是指哪个呢

樱花落人离去 2021-11-17 10:00:17

counter里面的

夜无邪 2021-11-17 08:43:19

我把*Count()里的cntLocalCopy=cnt;放到了usleep...;这后面了。后面执行后每次cnt每次就等于100了。正确的效果应该是这样的吗

各自安好 2021-11-16 17:31:05

你把
cntLocalCopy = cnt;这句话放到
r = 
rand
() % 2000; usleep(r);这句下面试试

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文