【发布时间】:2011-01-16 14:53:22
【问题描述】:
这是我对信号量和线程的第一次尝试。 我根据示例和网上找到的手册页构建了这段代码。 我对这段代码有两个疑问。
-
为什么每次尝试 semctl 时都会出现总线错误(我知道这是问题的根源,因为没有打印调试行 3)以及如何防止它?
李> 为什么尽管删除了 semctl(),但我无法获得关键部分的锁定?
我正在尝试执行以下代码:
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#define NUM 3
char c='a';
int semId=-1;
struct sembuf lockOperation = { 0, -1, 0};
struct sembuf unlockOperation = { 0, -1, 0};
void* PrintLetter()
{
int rc;
rc=semop(semId, &lockOperation, 1);
if(rc)
{
printf("\n Unable to lock\n");
exit(1);
}
printf("%c",c); //CRITICAL SECTION
c=c+1; //CRITICAL SECTION
rc = semop(semId, &unlockOperation, 1);
if(rc)
{
printf("\n Unable to unlock\n");
exit(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_t threads[NUM];
int rc=1;
long t;
printf("debug line 1\n");
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL);
if( semId == -1)
{
printf("\n Error in making the sem\n");
exit(1);
}
printf("debug line 2\n");
rc = semctl(semId, 0, SETVAL, (int)1); // Comment from here
if(rc)
{
printf("\n Unable to set val to 1\n");
exit(1);
} ////////////////////////////////// till here
printf("debug line 3\n");
for(t=0; t<NUM; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintLetter, NULL);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
sleep(3);
}
pthread_exit(NULL);
}
注意: 建议后我在代码中添加了以下内容:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};
还添加了以下内容:
union semun s_u;
s_u.val=1;
将 semctl 行改为
rc = semctl(semId, 0, SETVAL, s_u);
并进行了所有 rc 检查:
if(rc == -1)
semctl() 行仍然没有成功执行。 errno 现在指出: 权限被拒绝
更新:我可以使用以下更改摆脱“权限被拒绝”错误:
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0660);
现在,新问题是,我无法在控制台上打印“abc”。 该程序只打印“a”并挂起。不知道为什么。
最终更新: 我搞砸了解锁代码: 我用 -1 而不是 1 这是新代码:
struct sembuf unlockOperation = { 0, 1, 0};
感谢大家的帮助和耐心。
【问题讨论】:
-
注意:我想得到我的最终输出为 abc
-
@Carl:我使用的是 Solaris 机器。我在 linux 机器上尝试了同样的方法,得到了同样的“总线错误”。
-
我尝试添加以下行: union semun s_u; s_u.val=1; rc = semctl(semId, 0, SETVAL, s_u);我收到以下错误:sem.c:42: error: storage size of 's_u' is not known
-
注意:我在 Linux 机器上尝试了相同的代码。 semctl() 失败并以 printf("\n Unable to set val to 1\n"); 退出
标签: c multithreading unix semaphore